blob: ff580f2af9f86bb61cd63467cea2c4c4fb8ea5ce [file] [log] [blame]
Martin Roth9b1b3352016-02-24 12:27:06 -08001// This is the extra stuff added to the memtest+ from memtest.org
2// Code from Eric Nelson and Wee
3// (Checked without vendor-specific optimization before adding)
4/* extra.c -
5 *
6 * Released under version 2 of the Gnu Public License.
7 *
8 */
9
10#include "test.h"
11#include "screen_buffer.h"
12#include "pci.h"
13#include "extra.h"
14
15static int ctrl = -1;
16
17struct memory_controller {
18 unsigned vendor;
19 unsigned device;
20 int worked;
21 void (*change_timing)(int cas, int rcd, int rp, int ras);
22};
23
24static struct memory_controller mem_ctr[] = {
25
26 /* AMD 64*/
27 { 0x1022, 0x1100, 1, change_timing_amd64}, //AMD64 hypertransport link
28
29 /* nVidia */
30 { 0x10de, 0x01E0, 0, change_timing_nf2}, // nforce2
31
32 /* Intel */
33 { 0x8086, 0x2570, 0, change_timing_i875}, //Intel i848/i865
34 { 0x8086, 0x2578, 0, change_timing_i875}, //Intel i875P
35 { 0x8086, 0x2580, 0, change_timing_i925}, //Intel i915P/G
36 { 0x8086, 0x2584, 0, change_timing_i925}, //Intel i925X
37 { 0x8086, 0x2770, 0, change_timing_i925}, //Intel Lakeport
38 { 0x8086, 0x3580, 0, change_timing_i852}, //Intel i852GM - i855GM/GME (But not i855PM)
39};
40
41struct drc {
42 unsigned t_rwt;
43 unsigned t_wrt;
44 unsigned t_ref;
45 unsigned t_en2t;
46 unsigned t_rwqb;
47 unsigned t_rct;
48 unsigned t_rrd;
49 unsigned t_wr;
50};
51
52static struct drc a64;
53
54void find_memctr(void) // Basically copy from the find_controller function
55{
56 unsigned long vendor;
57 unsigned long device;
58 unsigned long a64;
59 int i= 0;
60 int result;
61
62 result = pci_conf_read(0, 0, 0, PCI_VENDOR_ID, 2, &vendor);
63 result = pci_conf_read(0, 0, 0, PCI_DEVICE_ID, 2, &device);
64
65 pci_conf_read(0, 24, 0, 0x00, 4, &a64);
66
67 if( a64 == 0x11001022) {
68 ctrl = 0;
69 return;
70 }
71
72 if (result == 0) {
73 for(i = 1; i < sizeof(mem_ctr)/sizeof(mem_ctr[0]); i++) {
74 if ((mem_ctr[i].vendor == vendor) &&
75 (mem_ctr[i].device == device))
76 {
77 ctrl = i;
78 return;
79 }
80 }
81 }
82 ctrl = -1;
83}
84
85void a64_parameter(void)
86{
87
88 ulong dramtlr;
89
90 if ( 0 == pci_conf_read(0, 24, 2, 0x88, 4, &dramtlr) )
91 {
92 a64.t_rct = 7 + ((dramtlr>>4) & 0x0F);
93 a64.t_rrd = 0 + ((dramtlr>>16) & 0x7);
94 a64.t_wr = 2 + ((dramtlr>>28) & 0x1);
95 }
96
97 if ( 0 == pci_conf_read(0, 24, 2, 0x8C, 4, &dramtlr) )
98 {
99 a64.t_rwt = 1 + ((dramtlr>>4) & 0x07);
100 a64.t_wrt = 1 + (dramtlr & 0x1);
101 a64.t_ref = 1 + ((dramtlr>>11) & 0x3);
102 }
103
104 if ( 0 == pci_conf_read(0, 24, 2, 0x90, 4, &dramtlr) )
105 {
106 a64.t_en2t = 1 + ((dramtlr>>28) & 0x1);
107 a64.t_rwqb = 2 << ((dramtlr>>14) & 0x3);
108 }
109}
110
111
112
113void change_timing(int cas, int rcd, int rp, int ras)
114{
115 find_memctr();
116 if ((ctrl == -1) || ( ctrl > sizeof(mem_ctr)/sizeof(mem_ctr[0])))
117 {
118 return;
119 }
120
121 mem_ctr[ctrl].change_timing(cas, rcd, rp, ras);
122 restart();
123}
124
125void amd64_option()
126{
127 int rwt=0, wrt=0, ref=0, en2t=0, rct=0, rrd=0, rwqb=0, wr = 0, flag=0;
128
129 if ((ctrl == -1) || ( ctrl > sizeof(mem_ctr)/sizeof(mem_ctr[0])))
130 {
131 return;
132 }
133
134 if (mem_ctr[ctrl].worked)
135 {
136 a64_parameter();
137 cprint(POP_Y+1, POP_X+4, "AMD64 options");
138
139 cprint(POP_Y+3, POP_X+4, "(1) Rd-Wr Delay : ");
140 dprint(POP_Y+3, POP_X+24, a64.t_rwt, 2, 0);
141
142 cprint(POP_Y+4, POP_X+4, "(2) Wr-Rd Delay : ");
143 dprint(POP_Y+4, POP_X+24, a64.t_wrt, 2, 0);
144
145 cprint(POP_Y+5, POP_X+4, "(3) Rd/Wr Bypass : ");
146 dprint(POP_Y+5, POP_X+24, a64.t_rwqb, 2, 0);
147
148 cprint(POP_Y+6, POP_X+4, "(4) Refresh Rate : ");
149 switch ( a64.t_ref)
150 {
151 case 1 : cprint(POP_Y+6, POP_X+23, "15.6us"); break;
152 case 2 : cprint(POP_Y+6, POP_X+23, " 7.8us"); break;
153 case 3 : cprint(POP_Y+6, POP_X+23, " 3.9us"); break;
154 }
155 cprint(POP_Y+7, POP_X+4, "(5) Command Rate :");
156 dprint(POP_Y+7, POP_X+24, a64.t_en2t, 2, 0);
157 cprint(POP_Y+7, POP_X+26, "T ");
158
159 cprint(POP_Y+8, POP_X+4, "(6) Row Cycle Time: ");
160 dprint(POP_Y+8, POP_X+24, a64.t_rct, 2, 0);
161
162 cprint(POP_Y+9, POP_X+4, "(7) RAS-RAS Delay : ");
163 dprint(POP_Y+9, POP_X+24, a64.t_rrd, 2, 0);
164
165 cprint(POP_Y+10, POP_X+4, "(8) Write Recovery: ");
166 dprint(POP_Y+10, POP_X+24, a64.t_wr, 2, 0);
167
168 cprint(POP_Y+11, POP_X+4,"(0) Cancel ");
169
170 while(!flag)
171 {
172 switch(get_key())
173 {
174 case 2:
175 popclear();
176 // read-to-write delay
177 cprint(POP_Y+3, POP_X+4, "Rd-Wr delay ");
178 cprint(POP_Y+4, POP_X+4, " (2 - 6 cycles)");
179 cprint(POP_Y+5, POP_X+4, "Current: ");
180 dprint(POP_Y+5, POP_X+14, a64.t_rwt, 4, 0);
181 cprint(POP_Y+7, POP_X+4, "New: ");
182 rwt = getval(POP_Y+7, POP_X+12, 0);
183 amd64_tweak(rwt, wrt, ref,en2t, rct, rrd, rwqb, wr);
184 break;
185
186 case 3:
187 popclear();
188 // read-to-write delay
189 cprint(POP_Y+3, POP_X+4, "Wr-Rd delay ");
190 cprint(POP_Y+4, POP_X+4, " (1 - 2 cycles)");
191 cprint(POP_Y+5, POP_X+4, "Current: ");
192 dprint(POP_Y+5, POP_X+14, a64.t_wrt, 4, 0);
193 cprint(POP_Y+7, POP_X+4, "New: ");
194 wrt = getval(POP_Y+7, POP_X+12, 0);
195 amd64_tweak(rwt, wrt, ref,en2t, rct, rrd, rwqb, wr);
196 break;
197
198 case 4:
199 popclear();
200 // Read write queue bypass count
201 cprint(POP_Y+3, POP_X+4, "Rd/Wr bypass ");
202 cprint(POP_Y+4, POP_X+4, " (2, 4 or 8 )");
203 cprint(POP_Y+5, POP_X+4, "Current: ");
204 dprint(POP_Y+5, POP_X+14, a64.t_rwqb, 2, 0);
205 cprint(POP_Y+7, POP_X+4, "New: ");
206 rwqb = getval(POP_Y+7, POP_X+11, 0);
207 amd64_tweak(rwt, wrt, ref,en2t, rct, rrd, rwqb, wr);
208 break;
209
210 case 5:
211 popclear();
212 // refresh rate
213 cprint(POP_Y+3, POP_X+4, "Refresh rate ");
214 cprint(POP_Y+4, POP_X+4, "Current: ");
215 switch ( a64.t_ref){
216 case 1 : cprint(POP_Y+4, POP_X+14, "15.6us"); break;
217 case 2 : cprint(POP_Y+4, POP_X+14, "7.8us "); break;
218 case 3 : cprint(POP_Y+4, POP_X+14, "3.9us "); break;
219 }
220 cprint(POP_Y+6, POP_X+4, "New: ");
221 cprint(POP_Y+7, POP_X+4, "(1) 15.6us");
222 cprint(POP_Y+8, POP_X+4, "(2) 7.8us ");
223 cprint(POP_Y+9, POP_X+4, "(3) 3.9us ");
224 ref = getval(POP_Y+6, POP_X+11, 0);
225 amd64_tweak(rwt, wrt, ref,en2t, rct, rrd, rwqb, wr);
226 break;
227
228 case 6:
229 popclear();
230 //Enable 2T command and addressing
231 cprint(POP_Y+3, POP_X+4, "Command rate:");
232 cprint(POP_Y+5, POP_X+4, "(1) 1T "); //only supoprted by CG revision and later
233 cprint(POP_Y+6, POP_X+4, "(2) 2T ");
234 en2t = getval(POP_Y+3, POP_X+22, 0);
235 amd64_tweak(rwt, wrt, ref,en2t, rct, rrd, rwqb, wr);
236 break;
237
238 case 7:
239 popclear();
240 //Row cycle time
241 cprint(POP_Y+3, POP_X+4, "Row cycle time: ");
242 cprint(POP_Y+4, POP_X+4, " (7 - 20 cycles)");
243 cprint(POP_Y+5, POP_X+4, "Current: ");
244 dprint(POP_Y+5, POP_X+14, a64.t_rct, 4, 0);
245 cprint(POP_Y+7, POP_X+4, "New: ");
246 rct = getval(POP_Y+7, POP_X+12, 0);
247 amd64_tweak(rwt, wrt, ref,en2t, rct, rrd, rwqb, wr);
248 break;
249
250 case 8:
251 popclear();
252 //Active-to-Active RAS Delay
253 cprint(POP_Y+3, POP_X+4, "RAS-RAS Delay: ");
254 cprint(POP_Y+4, POP_X+4, " (2 - 4 cycles)");
255 cprint(POP_Y+5, POP_X+4, "Current: ");
256 dprint(POP_Y+5, POP_X+14, a64.t_rrd, 2, 0);
257 cprint(POP_Y+7, POP_X+4, "New: ");
258 rrd = getval(POP_Y+7, POP_X+12, 0);
259 amd64_tweak(rwt, wrt, ref,en2t, rct, rrd, rwqb, wr);
260 break;
261
262 case 9:
263 popclear();
264 //Active-to-Active RAS Delay
265 cprint(POP_Y+3, POP_X+4, "Write Recovery: ");
266 cprint(POP_Y+4, POP_X+4, " (2 - 3 cycles)");
267 cprint(POP_Y+5, POP_X+4, "Current: ");
268 dprint(POP_Y+5, POP_X+14, a64.t_wr, 2, 0);
269 cprint(POP_Y+7, POP_X+4, "New: ");
270 wr = getval(POP_Y+7, POP_X+12, 0);
271 amd64_tweak(rwt, wrt, ref,en2t, rct, rrd, rwqb, wr);
272 break;
273
274 case 11:
275 case 57:
276 flag++;
277 /* 0/CR - Cancel */
278 break;
279 }
280 }
281 }
282}
283
284void get_option()
285{
286 int cas =0, rp=0, rcd=0, ras=0, sflag = 0 ;
287
288 while(!sflag)
289 {
290 switch(get_key())
291 {
292 case 2:
293 popclear();
294 cas = get_cas();
295 popclear();
296
297 cprint(POP_Y+3, POP_X+8, "tRCD: ");
298 rcd = getval(POP_Y+3, POP_X+15, 0);
299 popclear();
300
301 cprint(POP_Y+3, POP_X+8, "tRP: ");
302 rp = getval(POP_Y+3, POP_X+15, 0);
303 popclear();
304
305 cprint(POP_Y+3, POP_X+8, "tRAS: ");
306 ras = getval(POP_Y+3, POP_X+15, 0);
307 popclear();
308 change_timing(cas, rcd, rp, ras);
309 break;
310
311 case 3:
312 popclear();
313 cas = get_cas();
314 change_timing(cas, 0, 0, 0);
315 sflag++;
316 break;
317
318 case 4:
319 popclear();
320 cprint(POP_Y+3, POP_X+8, "tRCD: ");
321 rcd =getval(POP_Y+3, POP_X+15, 0);
322 change_timing(0, rcd, 0, 0);
323 sflag++;
324 break;
325
326 case 5:
327 popclear();
328 cprint(POP_Y+3, POP_X+8, "tRP: ");
329 rp =getval(POP_Y+3, POP_X+15, 0);
330 change_timing(0, 0, rp, 0);
331 sflag++;
332 break;
333
334 case 6:
335 popclear();
336 cprint(POP_Y+3, POP_X+8, "tRAS: ");
337 ras =getval(POP_Y+3, POP_X+15, 0);
338 change_timing(0, 0, 0, ras);
339 sflag++;
340 break;
341
342 case 7:
343 popclear();
344 amd64_option();
345 sflag++;
346 popclear();
347 break;
348
349 case 8:
350 break;
351
352 case 11:
353 case 57:
354 sflag++;
355 /* 0/CR - Cancel */
356 break;
357 }
358 }
359}
360
361void get_option_1()
362{
363 int rp=0, rcd=0, ras=0, sflag = 0 ;
364
365 while(!sflag)
366 {
367 switch(get_key())
368 {
369 case 2:
370 popclear();
371 cprint(POP_Y+3, POP_X+8, "tRCD: ");
372 rcd = getval(POP_Y+3, POP_X+15, 0);
373 popclear();
374
375 cprint(POP_Y+3, POP_X+8, "tRP: ");
376 rp = getval(POP_Y+3, POP_X+15, 0);
377 popclear();
378
379 cprint(POP_Y+3, POP_X+8, "tRAS: ");
380 ras = getval(POP_Y+3, POP_X+15, 0);
381 popclear();
382 change_timing(0, rcd, rp, ras);
383 break;
384
385 case 3:
386 popclear();
387 cprint(POP_Y+3, POP_X+8, "tRCD: ");
388 rcd =getval(POP_Y+3, POP_X+15, 0);
389 change_timing(0, rcd, 0, 0);
390 break;
391
392 case 4:
393 popclear();
394 cprint(POP_Y+3, POP_X+8, "tRP: ");
395 rp =getval(POP_Y+3, POP_X+15, 0);
396 change_timing(0, 0, rp, 0);
397 break;
398
399 case 5:
400 popclear();
401 cprint(POP_Y+3, POP_X+8, "tRAS: ");
402 ras =getval(POP_Y+3, POP_X+15, 0);
403 change_timing(0, 0, 0, ras);
404 break;
405
406 case 6:
407 popclear();
408 amd64_option();
409 sflag++;
410 popclear();
411 break;
412
413 case 7:
414 break;
415
416 case 11:
417 case 57:
418 sflag++;
419 /* 0/CR - Cancel */
420 break;
421 }
422 }
423}
424
425
426void get_menu(void)
427{
428 int menu ;
429
430 find_memctr();
431
432 switch(ctrl)
433 {
434 case 0: menu = 2; break;
435 case 1:
436 case 2:
437 case 3:
438 case 4: menu = 0; break;
439 case 5: menu = 1; break;
440 case 6: menu = 0; break;
441 default: menu = -1; break;
442 }
443
444 if (menu == -1)
445 {
446 popclear();
447 }
448 else if (menu == 0)
449 {
450 cprint(POP_Y+1, POP_X+2, "Modify Timing:");
451 cprint(POP_Y+3, POP_X+5, "(1) Modify All ");
452 cprint(POP_Y+4, POP_X+5, "(2) Modify tCAS ");
453 cprint(POP_Y+5, POP_X+5, "(3) Modify tRCD ");
454 cprint(POP_Y+6, POP_X+5, "(4) Modify tRP ");
455 cprint(POP_Y+7, POP_X+5, "(5) Modify tRAS ");
456 cprint(POP_Y+8, POP_X+5, "(0) Cancel");
457 wait_keyup();
458 get_option();
459 }
460 else if (menu == 1)
461 {
462 cprint(POP_Y+1, POP_X+2, "Modify Timing:");
463 cprint(POP_Y+3, POP_X+5, "(1) Modify All ");
464 cprint(POP_Y+4, POP_X+5, "(2) Modify tRCD ");
465 cprint(POP_Y+5, POP_X+5, "(3) Modify tRP ");
466 cprint(POP_Y+6, POP_X+5, "(4) Modify tRAS ");
467 cprint(POP_Y+7, POP_X+5, "(0) Cancel");
468 wait_keyup();
469 get_option();
470 }
471 else // AMD64 special menu
472 {
473 cprint(POP_Y+1, POP_X+2, "Modify Timing:");
474 cprint(POP_Y+3, POP_X+5, "(1) Modify All ");
475 cprint(POP_Y+4, POP_X+5, "(2) Modify tRCD ");
476 cprint(POP_Y+5, POP_X+5, "(3) Modify tRP ");
477 cprint(POP_Y+6, POP_X+5, "(4) Modify tRAS ");
478 cprint(POP_Y+7, POP_X+5, "(5) AMD64 Options");
479 cprint(POP_Y+8, POP_X+5, "(0) Cancel");
480 wait_keyup();
481 get_option_1();
482 }
483}
484
485int get_cas(void)
486{
487 int i852=0, cas=0;
488 ulong drc, ddr;
489 long *ptr;
490
491 switch(ctrl)
492 {
493 case 0: ddr = 1; break;
494 case 1:
495 case 2:
496 case 3: ddr = 1; break;
497 case 4:
498 pci_conf_read( 0, 0, 0, 0x44, 4, &ddr);
499 ddr &= 0xFFFFC000;
500 ptr=(long*)(ddr+0x120);
501 drc = *ptr;
502
503 if ((drc & 3) == 2) ddr = 2;
504 else ddr = 1;
505 break;
506 case 5: ddr = 2; break;
507 case 6: ddr = 1; i852 = 1; break;
508 default: ddr = 1;
509 }
510
511 if (ddr == 1)
512 {
513 cprint(POP_Y+3, POP_X+8, "tCAS: ");
514 cprint(POP_Y+5, POP_X+8, "(1) CAS 2.5 ");
515 cprint(POP_Y+6, POP_X+8, "(2) CAS 2 ");
516 if(!i852) {
517 cprint(POP_Y+7, POP_X+8, "(3) CAS 3 ");
518 }
519 cas = getval(POP_Y+3, POP_X+15, 0);
520 }
521 else if (ddr == 2)
522 {
523 cprint(POP_Y+3, POP_X+8, "tCAS: ");
524 cprint(POP_Y+5, POP_X+8, "(1) CAS 4 ");
525 cprint(POP_Y+6, POP_X+8, "(2) CAS 3 ");
526 cprint(POP_Y+7, POP_X+8, "(3) CAS 5 ");
527 cas = getval(POP_Y+3, POP_X+15, 0);
528 }
529 else
530 {
531 cas = -1;
532 }
533
534 popclear();
535 return (cas);
536}
537
538/////////////////////////////////////////////////////////
539// here we go for the exciting timing change part... //
540/////////////////////////////////////////////////////////
541
542void change_timing_i852(int cas, int rcd, int rp, int ras) {
543
544 ulong dramtlr;
545 ulong int1, int2;
546
547 pci_conf_read(0, 0, 1, 0x60, 4, &dramtlr);
548
549 // CAS Latency (tCAS)
550 int1 = dramtlr & 0xFF9F;
551 if (cas == 2) { int2 = int1 ^ 0x20; }
552 else if (cas == 1) { int2 = int1; }
553 else { int2 = dramtlr; }
554
555
556 // RAS-To-CAS (tRCD)
557 int1 = int2 & 0xFFF3;
558 if (rcd == 2) { int2 = int1 ^ 0x8; }
559 else if (rcd == 3) { int2 = int1 ^ 0x4; }
560 else if (rcd == 4) { int2 = int1; }
561 // else { int2 = int2; }
562
563
564 // RAS Precharge (tRP)
565 int1 = int2 & 0xFFFC;
566 if (rp == 2) { int2 = int1 ^ 0x2; }
567 else if (rp == 3) { int2 = int1 ^ 0x1; }
568 else if (rp == 4) { int2 = int1; }
569 // else { int2 = int2; }
570
571
572 // RAS Active to precharge (tRAS)
573 int1 = int2 & 0xF9FF;
574 if (ras == 5) { int2 = int1 ^ 0x0600; }
575 else if (ras == 6) { int2 = int1 ^ 0x0400; }
576 else if (ras == 7) { int2 = int1 ^ 0x0200; }
577 else if (ras == 8) { int2 = int1; }
578 // else { int2 = int2; }
579
580 pci_conf_write(0, 0, 1, 0x60, 4, int2);
581 __delay(500);
582}
583
584void change_timing_i925(int cas, int rcd, int rp, int ras)
585{
586 ulong int1, dev0, temp;
587 long *ptr;
588
589 //read MMRBAR
590 pci_conf_read( 0, 0, 0, 0x44, 4, &dev0);
591 dev0 &= 0xFFFFC000;
592
593 ptr=(long*)(dev0+0x114);
594 temp = *ptr;
595
596 // RAS-To-CAS (tRCD)
597 int1 = temp | 0x70;
598 if (rcd == 2) { temp = int1 ^ 0x70; }
599 else if (rcd == 3) { temp = int1 ^ 0x60; }
600 else if (rcd == 4) { temp = int1 ^ 0x50; }
601 else if (rcd == 5) { temp = int1 ^ 0x40; }
602 // else { temp = temp;}
603
604 //RAS precharge (tRP)
605 int1 = temp | 0x7;
606 if (rp == 2) { temp = int1 ^ 0x7; }
607 else if (rp == 3) { temp = int1 ^ 0x6; }
608 else if (rp == 4) { temp = int1 ^ 0x5; }
609 else if (rp == 5) { temp = int1 ^ 0x4; }
610 // else { temp = temp;}
611
612 if (mem_ctr[ctrl].device == 0x2770 ) // Lakeport?
613 {
614 // RAS Active to precharge (tRAS)
615 int1 = temp | 0xF80000; // bits 23:19
616 if (ras == 4) { temp = int1 ^ 0xD80000; }
617 else if (ras == 5) { temp = int1 ^ 0xD00000; }
618 else if (ras == 6) { temp = int1 ^ 0xC80000; }
619 else if (ras == 7) { temp = int1 ^ 0xC00000; }
620 else if (ras == 8) { temp = int1 ^ 0xB80000; }
621 else if (ras == 9) { temp = int1 ^ 0xB00000; }
622 else if (ras == 10) { temp = int1 ^ 0xA80000; }
623 else if (ras == 11) { temp = int1 ^ 0xA00000; }
624 else if (ras == 12) { temp = int1 ^ 0x980000; }
625 else if (ras == 13) { temp = int1 ^ 0x900000; }
626 else if (ras == 14) { temp = int1 ^ 0x880000; }
627 else if (ras == 15) { temp = int1 ^ 0x800000; }
628 // else { temp = temp;}
629 }
630 else
631 {
632 // RAS Active to precharge (tRAS)
633 int1 = temp | 0xF00000; // bits 23:20
634 if (ras == 4) { temp = int1 ^ 0xB00000; }
635 else if (ras == 5) { temp = int1 ^ 0xA00000; }
636 else if (ras == 6) { temp = int1 ^ 0x900000; }
637 else if (ras == 7) { temp = int1 ^ 0x800000; }
638 else if (ras == 8) { temp = int1 ^ 0x700000; }
639 else if (ras == 9) { temp = int1 ^ 0x600000; }
640 else if (ras == 10) { temp = int1 ^ 0x500000; }
641 else if (ras == 11) { temp = int1 ^ 0x400000; }
642 else if (ras == 12) { temp = int1 ^ 0x300000; }
643 else if (ras == 13) { temp = int1 ^ 0x200000; }
644 else if (ras == 14) { temp = int1 ^ 0x100000; }
645 else if (ras == 15) { temp = int1 ^ 0x000000; }
646 // else { temp = temp;}
647 }
648
649 // CAS Latency (tCAS)
650 int1 = temp | 0x0300;
651 if (cas == 1) { temp = int1 ^ 0x200; } // cas 2.5
652 else if (cas == 2) { temp = int1 ^ 0x100; }
653 else if (cas == 3) { temp = int1 ^ 0x300; }
654 // else { temp = temp;}
655
656 *ptr = temp;
657 __delay(500);
658 return;
659}
660
661void change_timing_Lakeport(int cas, int rcd, int rp, int ras)
662{
663 ulong int1, dev0, temp;
664 long *ptr;
665
666 //read MMRBAR
667 pci_conf_read( 0, 0, 0, 0x44, 4, &dev0);
668 dev0 &= 0xFFFFC000;
669
670 ptr=(long*)(dev0+0x114);
671 temp = *ptr;
672
673 // RAS-To-CAS (tRCD)
674 int1 = temp | 0x70;
675 if (rcd == 2) { temp = int1 ^ 0x70; }
676 else if (rcd == 3) { temp = int1 ^ 0x60; }
677 else if (rcd == 4) { temp = int1 ^ 0x50; }
678 else if (rcd == 5) { temp = int1 ^ 0x40; }
679 // else { temp = temp;}
680
681 //RAS precharge (tRP)
682 int1 = temp | 0x7;
683 if (rp == 2) { temp = int1 ^ 0x7; }
684 else if (rp == 3) { temp = int1 ^ 0x6; }
685 else if (rp == 4) { temp = int1 ^ 0x5; }
686 else if (rp == 5) { temp = int1 ^ 0x4; }
687 // else { temp = temp;}
688
689
690 // CAS Latency (tCAS)
691 int1 = temp | 0x0300;
692 if (cas == 1) { temp = int1 ^ 0x200; } // cas 2.5
693 else if (cas == 2) { temp = int1 ^ 0x100; }
694 else if (cas == 3) { temp = int1 ^ 0x300; }
695 // else { temp = temp;}
696
697 *ptr = temp;
698 __delay(500);
699 return;
700}
701
702void change_timing_i875(int cas, int rcd, int rp, int ras){
703
704 ulong int1, dev6, temp;
705 long *ptr;
706
707 /* Read the MMR Base Address & Define the pointer from the BAR6 overflow register */
708 pci_conf_read( 0, 6, 0, 0x10, 4, &dev6);
709
710 ptr=(long*)(dev6+0x60);
711
712 temp = *ptr;
713
714 // RAS-To-CAS (tRCD)
715 int1 = temp | 0xC;
716 if (rcd == 2) { temp = int1 ^ 0x4; }
717 else if (rcd == 3) { temp = int1 ^ 0x8; }
718 else if (rcd == 4) { temp = int1 ^ 0xC; }
719 else if (rcd == 5) { temp = int1 ^ 0xC; }
720 // else { temp = temp;}
721
722
723 //RAS precharge (tRP)
724 int1 = temp | 0x3;
725 if (rp == 2) { temp = int1 ^ 0x1; }
726 else if (rp == 3) { temp = int1 ^ 0x2; }
727 else if (rp == 4) { temp = int1 ^ 0x3; }
728 else if (rp == 5) { temp = int1 ^ 0x3; }
729 // else { temp = temp;}
730
731
732 // RAS Active to precharge (tRAS)
733 int1 = temp | 0x380;
734 if (ras == 5) { temp = int1 ^ 0x100; }
735 else if (ras == 6) { temp = int1 ^ 0x180; }
736 else if (ras == 7) { temp = int1 ^ 0x200; }
737 else if (ras == 8) { temp = int1 ^ 0x280; }
738 else if (ras == 9) { temp = int1 ^ 0x300; }
739 else if (ras == 10) { temp = int1 ^ 0x380; }
740 // else { temp = temp;}
741
742 // CAS Latency (tCAS)
743 int1 = temp | 0x60;
744 if (cas == 1) { temp = int1 ^ 0x60; } // cas 2.5
745 else if (cas == 2) { temp = int1 ^ 0x40; }
746 else if (cas == 3) { temp = int1 ^ 0x20; }
747 // else { temp = temp; }
748
749 *ptr = temp;
750 __delay(500);
751 return;
752}
753
754
755void change_timing_nf2(int cas, int rcd, int rp, int ras) {
756
757 ulong dramtlr, dramtlr2;
758 ulong int1, int2;
759
760 pci_conf_read(0, 0, 1, 0x90, 4, &dramtlr);
761 pci_conf_read(0, 0, 1, 0xA0, 4, &dramtlr2);
762
763
764 // CAS Latency (tCAS)
765 int1 = dramtlr2 | 0x0070;
766 if (cas == 1) { int2 = int1 ^ 0x10; } // cas = 2.5
767 else if (cas == 2) { int2 = int1 ^ 0x50; }
768 else if (cas == 3) { int2 = int1 ^ 0x40; }
769 else { int2 = dramtlr2; }
770
771 pci_conf_write(0, 0, 1, 0xA0, 4, int2);
772
773 // RAS-To-CAS (tRCD)
774
775 int1 = dramtlr | 0x700000;
776 if (rcd == 2) { int2 = int1 ^ 0x500000; }
777 else if (rcd == 3) { int2 = int1 ^ 0x400000; }
778 else if (rcd == 4) { int2 = int1 ^ 0x300000; }
779 else if (rcd == 5) { int2 = int1 ^ 0x200000; }
780 else if (rcd == 6) { int2 = int1 ^ 0x100000; }
781 else { int2 = dramtlr;}
782
783
784 // RAS Precharge (tRP)
785 int1 = int2 | 0x70000000;
786 if (rp == 2) { int2 = int1 ^ 0x50000000; }
787 else if (rp == 3) { int2 = int1 ^ 0x40000000; }
788 else if (rp == 4) { int2 = int1 ^ 0x30000000; }
789 else if (rp == 5) { int2 = int1 ^ 0x20000000; }
790 else if (rp == 6) { int2 = int1 ^ 0x10000000; }
791 // else { int2 = int2;}
792
793
794 // RAS Active to precharge (tRAS)
795
796 int1 = int2 | 0x78000;
797 if (ras == 4) { int2 = int1 ^ 0x58000; }
798 else if (ras == 5) { int2 = int1 ^ 0x50000; }
799 else if (ras == 6) { int2 = int1 ^ 0x48000; }
800 else if (ras == 7) { int2 = int1 ^ 0x40000; }
801 else if (ras == 8) { int2 = int1 ^ 0x38000; }
802 else if (ras == 9) { int2 = int1 ^ 0x30000; }
803 else if (ras == 10) { int2 = int1 ^ 0x28000; }
804 else if (ras == 11) { int2 = int1 ^ 0x20000; }
805 else if (ras == 12) { int2 = int1 ^ 0x18000; }
806 else if (ras == 13) { int2 = int1 ^ 0x10000; }
807 else if (ras == 14) { int2 = int1 ^ 0x08000; }
808 // else { int2 = int2;}
809
810
811 pci_conf_write(0, 0, 1, 0x90, 4, int2);
812 __delay(500);
813}
814
815
816void change_timing_amd64(int cas, int rcd, int rp, int ras) {
817
818 ulong dramtlr;
819 ulong int1= 0x0;
820
821 pci_conf_read(0, 24, 2, 0x88, 4, &dramtlr);
822
823 // RAS-To-CAS (tRCD)
824 int1 = dramtlr | 0x7000;
825 if (rcd == 2) { dramtlr = int1 ^ 0x5000; }
826 else if (rcd == 3) { dramtlr = int1 ^ 0x4000; }
827 else if (rcd == 4) { dramtlr = int1 ^ 0x3000; }
828 else if (rcd == 5) { dramtlr = int1 ^ 0x2000; }
829 else if (rcd == 6) { dramtlr = int1 ^ 0x1000; }
830 else if (rcd == 1) { dramtlr = int1 ^ 0x6000; }
831 // else { dramtlr = dramtlr;}
832
833
834 //RAS precharge (tRP)
835 int1 = dramtlr | 0x7000000;
836 if (rp == 2) { dramtlr = int1 ^ 0x5000000; }
837 else if (rp == 3) { dramtlr = int1 ^ 0x4000000; }
838 else if (rp == 1) { dramtlr = int1 ^ 0x6000000; }
839 else if (rp == 4) { dramtlr = int1 ^ 0x3000000; }
840 else if (rp == 5) { dramtlr = int1 ^ 0x2000000; }
841 else if (rp == 6) { dramtlr = int1 ^ 0x1000000; }
842 // else { dramtlr = dramtlr;}
843
844
845 // RAS Active to precharge (tRAS)
846 int1 = dramtlr | 0xF00000;
847 if (ras == 5) { dramtlr = int1 ^ 0xA00000; }
848 else if (ras == 6) { dramtlr = int1 ^ 0x900000; }
849 else if (ras == 7) { dramtlr = int1 ^ 0x800000; }
850 else if (ras == 8) { dramtlr = int1 ^ 0x700000; }
851 else if (ras == 9) { dramtlr = int1 ^ 0x600000; }
852 else if (ras == 10) { dramtlr = int1 ^ 0x500000; }
853 else if (ras == 11) { dramtlr = int1 ^ 0x400000; }
854 else if (ras == 12) { dramtlr = int1 ^ 0x300000; }
855 else if (ras == 13) { dramtlr = int1 ^ 0x200000; }
856 else if (ras == 14) { dramtlr = int1 ^ 0x100000; }
857 // else { dramtlr = dramtlr;}
858
859
860 // CAS Latency (tCAS)
861 int1 = dramtlr | 0x7; // some changes will cause the system hang, tried Draminit to no avail
862 if (cas == 1) { dramtlr = int1 ^ 0x2; } // cas 2.5
863 else if (cas == 2) { dramtlr = int1 ^ 0x6; }
864 else if (cas == 3) { dramtlr = int1 ^ 0x5; }
865 else if (cas == 4) { dramtlr = int1 ^ 0x7; } //cas 1.5 on a64
866 // else { dramtlr = dramtlr; }
867
868// pci_conf_read(0, 24, 2, 0x90, 4, &dramcr);// use dram init
869 pci_conf_write(0, 24, 2, 0x88, 4, dramtlr);
870 __delay(500);
871
872////////////////////////////////////////////////////////////////
873// trying using the draminit, but do not work
874}
875
876// copy from lib.c code to add delay to chipset timing modification
877void __delay(ulong loops)
878{
879 int d0;
880 __asm__ __volatile__(
881 "\tjmp 1f\n"
882 ".align 16\n"
883 "1:\tjmp 2f\n"
884 ".align 16\n"
885 "2:\tdecl %0\n\tjns 2b"
886 :"=&a" (d0)
887 :"0" (loops));
888}
889
890void amd64_tweak(int rwt, int wrt, int ref, int en2t, int rct, int rrd, int rwqb, int wr)
891{
892 ulong dramtlr;
893 ulong int1= 0x0;
894
895 pci_conf_read(0, 24, 2, 0x88, 4, &dramtlr);
896
897 // Row Cycle time
898 int1 = dramtlr | 0xF0;
899 if (rct == 7 ) { dramtlr = int1 ^ 0xF0; }
900 else if (rct == 8 ) { dramtlr = int1 ^ 0xE0; }
901 else if (rct == 9 ) { dramtlr = int1 ^ 0xD0; }
902 else if (rct == 10) { dramtlr = int1 ^ 0xC0; }
903 else if (rct == 11) { dramtlr = int1 ^ 0xB0; }
904 else if (rct == 12) { dramtlr = int1 ^ 0xA0; }
905 else if (rct == 13) { dramtlr = int1 ^ 0x90; }
906 else if (rct == 14) { dramtlr = int1 ^ 0x80; }
907 else if (rct == 15) { dramtlr = int1 ^ 0x70; }
908 else if (rct == 16) { dramtlr = int1 ^ 0x60; }
909 else if (rct == 17) { dramtlr = int1 ^ 0x50; }
910 else if (rct == 18) { dramtlr = int1 ^ 0x40; }
911 else if (rct == 19) { dramtlr = int1 ^ 0x30; }
912 else if (rct == 20) { dramtlr = int1 ^ 0x20; }
913 // else { dramtlr = dramtlr;}
914
915 //Active-avtive ras-ras delay
916 int1 = dramtlr | 0x70000;
917 if (rrd == 2) { dramtlr = int1 ^ 0x50000; } // 2 bus clocks
918 else if (rrd == 3) { dramtlr = int1 ^ 0x40000; } // 3 bus clocks
919 else if (rrd == 4) { dramtlr = int1 ^ 0x30000; } // 4 bus clocks
920 // else { dramtlr = dramtlr;}
921
922 //Write recovery time
923 int1 = dramtlr | 0x10000000;
924 if (wr == 2) { dramtlr = int1 ^ 0x10000000; } // 2 bus clocks
925 else if (wr == 3) { dramtlr = int1 ^ 0x00000000; } // 3 bus clocks
926 // else { dramtlr = dramtlr;}
927
928 pci_conf_write(0, 24, 2, 0x88, 4, dramtlr);
929 __delay(500);
930 //////////////////////////////////////////////
931
932 pci_conf_read(0, 24, 2, 0x8C, 4, &dramtlr);
933
934 // Write-to read delay
935 int1 = dramtlr | 0x1;
936 if (wrt == 2) { dramtlr = int1 ^ 0x0; }
937 else if (wrt == 1) { dramtlr = int1 ^ 0x1; }
938 // else { dramtlr = dramtlr;}
939
940 // Read-to Write delay
941 int1 = dramtlr | 0x70;
942 if (rwt == 1) { dramtlr = int1 ^ 0x70; }
943 else if (rwt == 2) { dramtlr = int1 ^ 0x60; }
944 else if (rwt == 3) { dramtlr = int1 ^ 0x50; }
945 else if (rwt == 4) { dramtlr = int1 ^ 0x40; }
946 else if (rwt == 5) { dramtlr = int1 ^ 0x30; }
947 else if (rwt == 6) { dramtlr = int1 ^ 0x20; }
948 // else { dramtlr = dramtlr;}
949
950 //Refresh Rate
951 int1 = dramtlr | 0x1800;
952 if (ref == 1) { dramtlr = int1 ^ 0x1800; } // 15.6us
953 else if (ref == 2) { dramtlr = int1 ^ 0x1000; } // 7.8us
954 else if (ref == 3) { dramtlr = int1 ^ 0x0800; } // 3.9us
955 // else { dramtlr = dramtlr;}
956
957 pci_conf_write(0, 24, 2, 0x8c, 4, dramtlr);
958 __delay(500);
959 /////////////////////////////////////
960
961 pci_conf_read(0, 24, 2, 0x90, 4, &dramtlr);
962
963 // Enable 2t command
964 int1 = dramtlr | 0x10000000;
965 if (en2t == 2) { dramtlr = int1 ^ 0x00000000; } // 2T
966 else if (en2t == 1) { dramtlr = int1 ^ 0x10000000; } // 1T
967 // else { dramtlr = dramtlr;}
968
969 // Read Write queue bypass count
970 int1 = dramtlr | 0xC000;
971 if (rwqb == 2) { dramtlr = int1 ^ 0xC000; }
972 else if (rwqb == 4) { dramtlr = int1 ^ 0x8000; }
973 else if (rwqb == 8) { dramtlr = int1 ^ 0x4000; }
974 else if (rwqb == 16) { dramtlr = int1 ^ 0x0000; }
975 // else { dramtlr = dramtlr;}
976
977 pci_conf_write(0, 24, 2, 0x90, 4, dramtlr);
978 __delay(500);
979 restart();
980}
981