blob: d20ae6d4314a73849f1e492e9fe21bf3c5f28228 [file] [log] [blame]
Eric Biederman6aa31cc2003-06-10 21:22:07 +00001#define HAVE_STRING_SUPPORT 1
2#define HAVE_CAST_SUPPORT 1
3#define HAVE_STATIC_ARRAY_SUPPORT 1
4#define HAVE_POINTER_SUPPORT 1
5#define HAVE_MACRO_ARG_SUPPORT 0
Eric Biedermanb138ac82003-04-22 18:44:01 +00006
7void outb(unsigned char value, unsigned short port)
8{
9 __builtin_outb(value, port);
10}
11
12void outw(unsigned short value, unsigned short port)
13{
14 __builtin_outw(value, port);
15}
16
17void outl(unsigned int value, unsigned short port)
18{
19 __builtin_outl(value, port);
20}
21
22unsigned char inb(unsigned short port)
23{
24 return __builtin_inb(port);
25}
26
27unsigned char inw(unsigned short port)
28{
29 return __builtin_inw(port);
30}
31
32unsigned char inl(unsigned short port)
33{
34 return __builtin_inl(port);
35}
36
37static unsigned int config_cmd(unsigned char bus, unsigned devfn, unsigned where)
38{
39 return 0x80000000 | (bus << 16) | (devfn << 8) | (where & ~3);
40}
41
42static unsigned char pcibios_read_config_byte(
43 unsigned char bus, unsigned devfn, unsigned where)
44{
45 outl(config_cmd(bus, devfn, where), 0xCF8);
46 return inb(0xCFC + (where & 3));
47}
48
49static unsigned short pcibios_read_config_word(
50 unsigned char bus, unsigned devfn, unsigned where)
51{
52 outl(config_cmd(bus, devfn, where), 0xCF8);
53 return inw(0xCFC + (where & 2));
54}
55
56static unsigned int pcibios_read_config_dword(
57 unsigned char bus, unsigned devfn, unsigned where)
58{
59 outl(config_cmd(bus, devfn, where), 0xCF8);
60 return inl(0xCFC);
61}
62
63
64static void pcibios_write_config_byte(
65 unsigned char bus, unsigned devfn, unsigned where, unsigned char value)
66{
67 outl(config_cmd(bus, devfn, where), 0xCF8);
68 outb(value, 0xCFC + (where & 3));
69}
70
71static void pcibios_write_config_word(
72 unsigned char bus, unsigned devfn, unsigned where, unsigned short value)
73{
74 outl(config_cmd(bus, devfn, where), 0xCF8);
75 outw(value, 0xCFC + (where & 2));
76}
77
78static void pcibios_write_config_dword(
79 unsigned char bus, unsigned devfn, unsigned where, unsigned int value)
80{
81 outl(config_cmd(bus, devfn, where), 0xCF8);
82 outl(value, 0xCFC);
83}
84
85/* Base Address */
Stefan Reinauer08670622009-06-30 15:17:49 +000086#ifndef CONFIG_TTYS0_BASE
87#define CONFIG_TTYS0_BASE 0x3f8
Eric Biedermanb138ac82003-04-22 18:44:01 +000088#endif
89
Stefan Reinauer08670622009-06-30 15:17:49 +000090#ifndef CONFIG_TTYS0_BAUD
91#define CONFIG_TTYS0_BAUD 115200
Eric Biedermanb138ac82003-04-22 18:44:01 +000092#endif
93
Stefan Reinauer08670622009-06-30 15:17:49 +000094#if ((115200%CONFIG_TTYS0_BAUD) != 0)
Eric Biedermanb138ac82003-04-22 18:44:01 +000095#error Bad ttys0 baud rate
96#endif
97
Stefan Reinauer08670622009-06-30 15:17:49 +000098#define CONFIG_TTYS0_DIV (115200/CONFIG_TTYS0_BAUD)
Eric Biedermanb138ac82003-04-22 18:44:01 +000099
100/* Line Control Settings */
Stefan Reinauer08670622009-06-30 15:17:49 +0000101#ifndef CONFIG_TTYS0_LCS
Eric Biedermanb138ac82003-04-22 18:44:01 +0000102/* Set 8bit, 1 stop bit, no parity */
Stefan Reinauer08670622009-06-30 15:17:49 +0000103#define CONFIG_TTYS0_LCS 0x3
Eric Biedermanb138ac82003-04-22 18:44:01 +0000104#endif
105
Stefan Reinauer08670622009-06-30 15:17:49 +0000106#define UART_LCS CONFIG_TTYS0_LCS
Eric Biedermanb138ac82003-04-22 18:44:01 +0000107
108/* Data */
109#define UART_RBR 0x00
110#define UART_TBR 0x00
111
112/* Control */
113#define UART_IER 0x01
114#define UART_IIR 0x02
115#define UART_FCR 0x02
116#define UART_LCR 0x03
117#define UART_MCR 0x04
118#define UART_DLL 0x00
119#define UART_DLM 0x01
120
121/* Status */
122#define UART_LSR 0x05
123#define UART_MSR 0x06
124#define UART_SCR 0x07
125
126int uart_can_tx_byte(void)
127{
Stefan Reinauer08670622009-06-30 15:17:49 +0000128 return inb(CONFIG_TTYS0_BASE + UART_LSR) & 0x20;
Eric Biedermanb138ac82003-04-22 18:44:01 +0000129}
130
131void uart_wait_to_tx_byte(void)
132{
133 while(!uart_can_tx_byte())
134 ;
135}
136
137void uart_wait_until_sent(void)
138{
Stefan Reinauer14e22772010-04-27 06:56:47 +0000139 while(!(inb(CONFIG_TTYS0_BASE + UART_LSR) & 0x40))
Eric Biedermanb138ac82003-04-22 18:44:01 +0000140 ;
141}
142
143void uart_tx_byte(unsigned char data)
144{
145 uart_wait_to_tx_byte();
Stefan Reinauer08670622009-06-30 15:17:49 +0000146 outb(data, CONFIG_TTYS0_BASE + UART_TBR);
Eric Biedermanb138ac82003-04-22 18:44:01 +0000147 /* Make certain the data clears the fifos */
148 uart_wait_until_sent();
149}
150
151void uart_init(void)
152{
153 /* disable interrupts */
Stefan Reinauer08670622009-06-30 15:17:49 +0000154 outb(0x0, CONFIG_TTYS0_BASE + UART_IER);
Eric Biedermanb138ac82003-04-22 18:44:01 +0000155 /* enable fifo's */
Stefan Reinauer08670622009-06-30 15:17:49 +0000156 outb(0x01, CONFIG_TTYS0_BASE + UART_FCR);
Eric Biedermanb138ac82003-04-22 18:44:01 +0000157 /* Set Baud Rate Divisor to 12 ==> 115200 Baud */
Stefan Reinauer08670622009-06-30 15:17:49 +0000158 outb(0x80 | UART_LCS, CONFIG_TTYS0_BASE + UART_LCR);
159 outb(CONFIG_TTYS0_DIV & 0xFF, CONFIG_TTYS0_BASE + UART_DLL);
160 outb((CONFIG_TTYS0_DIV >> 8) & 0xFF, CONFIG_TTYS0_BASE + UART_DLM);
161 outb(UART_LCS, CONFIG_TTYS0_BASE + UART_LCR);
Eric Biedermanb138ac82003-04-22 18:44:01 +0000162}
163
164void __console_tx_char(unsigned char byte)
165{
166 uart_tx_byte(byte);
167}
168void __console_tx_nibble(unsigned nibble)
169{
170 unsigned char digit;
171 digit = nibble + '0';
172 if (digit > '9') {
173 digit += 39;
174 }
175 __console_tx_char(digit);
176}
177void __console_tx_hex8(unsigned char byte)
178{
179 __console_tx_nibble(byte >> 4);
180 __console_tx_nibble(byte & 0x0f);
181}
182
183void __console_tx_hex32(unsigned char value)
184{
185 __console_tx_nibble((value >> 28) & 0x0f);
186 __console_tx_nibble((value >> 24) & 0x0f);
187 __console_tx_nibble((value >> 20) & 0x0f);
188 __console_tx_nibble((value >> 16) & 0x0f);
189 __console_tx_nibble((value >> 12) & 0x0f);
190 __console_tx_nibble((value >> 8) & 0x0f);
191 __console_tx_nibble((value >> 4) & 0x0f);
192 __console_tx_nibble(value & 0x0f);
193}
194
195#if HAVE_STRING_SUPPORT
196void __console_tx_string(char *str)
197{
198 unsigned char ch;
199 while((ch = *str++) != '\0') {
Eric Biederman6aa31cc2003-06-10 21:22:07 +0000200 __console_tx_char(ch);
Eric Biedermanb138ac82003-04-22 18:44:01 +0000201 }
202}
203#else
204void __console_tx_string(char *str)
205{
206}
207#endif
208
209
210void print_emerg_char(unsigned char byte) { __console_tx_char(byte); }
211void print_emerg_hex8(unsigned char value) { __console_tx_hex8(value); }
212void print_emerg_hex32(unsigned int value) { __console_tx_hex32(value); }
213void print_emerg(char *str) { __console_tx_string(str); }
214
215void print_alert_char(unsigned char byte) { __console_tx_char(byte); }
216void print_alert_hex8(unsigned char value) { __console_tx_hex8(value); }
217void print_alert_hex32(unsigned int value) { __console_tx_hex32(value); }
218void print_alert(char *str) { __console_tx_string(str); }
219
220void print_crit_char(unsigned char byte) { __console_tx_char(byte); }
221void print_crit_hex8(unsigned char value) { __console_tx_hex8(value); }
222void print_crit_hex32(unsigned int value) { __console_tx_hex32(value); }
223void print_crit(char *str) { __console_tx_string(str); }
224
225void print_err_char(unsigned char byte) { __console_tx_char(byte); }
226void print_err_hex8(unsigned char value) { __console_tx_hex8(value); }
227void print_err_hex32(unsigned int value) { __console_tx_hex32(value); }
228void print_err(char *str) { __console_tx_string(str); }
229
230void print_warning_char(unsigned char byte) { __console_tx_char(byte); }
231void print_warning_hex8(unsigned char value) { __console_tx_hex8(value); }
232void print_warning_hex32(unsigned int value) { __console_tx_hex32(value); }
233void print_warning(char *str) { __console_tx_string(str); }
234
235void print_notice_char(unsigned char byte) { __console_tx_char(byte); }
236void print_notice_hex8(unsigned char value) { __console_tx_hex8(value); }
237void print_notice_hex32(unsigned int value) { __console_tx_hex32(value); }
238void print_notice(char *str) { __console_tx_string(str); }
239
240void print_info_char(unsigned char byte) { __console_tx_char(byte); }
241void print_info_hex8(unsigned char value) { __console_tx_hex8(value); }
242void print_info_hex32(unsigned int value) { __console_tx_hex32(value); }
243void print_info(char *str) { __console_tx_string(str); }
244
245void print_debug_char(unsigned char byte) { __console_tx_char(byte); }
246void print_debug_hex8(unsigned char value) { __console_tx_hex8(value); }
247void print_debug_hex32(unsigned int value) { __console_tx_hex32(value); }
248void print_debug(char *str) { __console_tx_string(str); }
249
250void print_spew_char(unsigned char byte) { __console_tx_char(byte); }
251void print_spew_hex8(unsigned char value) { __console_tx_hex8(value); }
252void print_spew_hex32(unsigned int value) { __console_tx_hex32(value); }
253void print_spew(char *str) { __console_tx_string(str); }
254
255#define PIIX4_DEVFN 0x90
256#define SMBUS_MEM_DEVICE_START 0x50
257#define SMBUS_MEM_DEVICE_END 0x53
258#define SMBUS_MEM_DEVICE_INC 1
259
260
261#define PM_BUS 0
262#define PM_DEVFN (PIIX4_DEVFN+3)
263
264#define SMBUS_IO_BASE 0x1000
265#define SMBHSTSTAT 0
266#define SMBHSTCTL 2
267#define SMBHSTCMD 3
268#define SMBHSTADD 4
269#define SMBHSTDAT0 5
270#define SMBHSTDAT1 6
271#define SMBBLKDAT 7
272
273void smbus_enable(void)
274{
275 /* iobase addr */
276 pcibios_write_config_dword(PM_BUS, PM_DEVFN, 0x90, SMBUS_IO_BASE | 1);
277 /* smbus enable */
278 pcibios_write_config_byte(PM_BUS, PM_DEVFN, 0xd2, (0x4 << 1) | 1);
279 /* iospace enable */
280 pcibios_write_config_word(PM_BUS, PM_DEVFN, 0x4, 1);
281}
282
283void smbus_setup(void)
284{
285 outb(0, SMBUS_IO_BASE + SMBHSTSTAT);
286}
287
288static void smbus_wait_until_ready(void)
289{
290 while((inb(SMBUS_IO_BASE + SMBHSTSTAT) & 1) == 1) {
291 /* nop */
292 }
293}
294
295static void smbus_wait_until_done(void)
296{
297 unsigned char byte;
298 do {
299 byte = inb(SMBUS_IO_BASE + SMBHSTSTAT);
300 }while((byte &1) == 1);
301 while( (byte & ~1) == 0) {
302 byte = inb(SMBUS_IO_BASE + SMBHSTSTAT);
303 }
304}
305
306int smbus_read_byte(unsigned device, unsigned address)
307{
308 unsigned char host_status_register;
309 unsigned char byte;
310 int result;
311
312 smbus_wait_until_ready();
313
314 /* setup transaction */
315 /* disable interrupts */
316 outb(inb(SMBUS_IO_BASE + SMBHSTCTL) & (~1), SMBUS_IO_BASE + SMBHSTCTL);
317 /* set the device I'm talking too */
318 outb(((device & 0x7f) << 1) | 1, SMBUS_IO_BASE + SMBHSTADD);
319 /* set the command/address... */
320 outb(address & 0xFF, SMBUS_IO_BASE + SMBHSTCMD);
321 /* set up for a byte data read */
322 outb((inb(SMBUS_IO_BASE + SMBHSTCTL) & 0xE3) | (0x2 << 2), SMBUS_IO_BASE + SMBHSTCTL);
323
324 /* clear any lingering errors, so the transaction will run */
325 outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT);
326
327 /* clear the data byte...*/
328 outb(0, SMBUS_IO_BASE + SMBHSTDAT0);
329
330 /* start the command */
331 outb((inb(SMBUS_IO_BASE + SMBHSTCTL) | 0x40), SMBUS_IO_BASE + SMBHSTCTL);
332
333 /* poll for transaction completion */
334 smbus_wait_until_done();
335
336 host_status_register = inb(SMBUS_IO_BASE + SMBHSTSTAT);
337
338 /* read results of transaction */
339 byte = inb(SMBUS_IO_BASE + SMBHSTDAT0);
340
341 result = byte;
342 if (host_status_register != 0x02) {
343 result = -1;
344 }
345 return result;
346}
347
348#define I440GX_BUS 0
349#define I440GX_DEVFN ((0x00 << 3) + 0)
350
351#define USE_ECC 0
352
353#define CAS_LATENCY 3
354
355 /* CAS latency 2 */
356#if (CAS_LATENCY == 2)
357#define CAS_NB 0x17
Stefan Reinauer14e22772010-04-27 06:56:47 +0000358 /*
Eric Biedermanb138ac82003-04-22 18:44:01 +0000359 * 7 == 0111
360 * 1 == 0001
361 */
362#define CAS_MODE 0x2a
363 /*
364 * a == 1010
365 * 2 == 0010
366 */
367#endif
368
369 /* CAS latency 3 */
Stefan Reinauer14e22772010-04-27 06:56:47 +0000370#if (CAS_LATENCY == 3)
Eric Biedermanb138ac82003-04-22 18:44:01 +0000371#define CAS_NB 0x13
372 /*
373 * 3 == 0011
374 * 1 == 0001
375 */
376#define CAS_MODE 0x3a
377 /*
378 * a == 1010
379 * 3 == 0011
380 */
381#endif
382
383#ifndef CAS_NB
Stefan Reinauer14e22772010-04-27 06:56:47 +0000384#error "Nothing defined"
Eric Biedermanb138ac82003-04-22 18:44:01 +0000385#endif
386
387/* Default values for config registers */
Stefan Reinauer14e22772010-04-27 06:56:47 +0000388
Eric Biedermanb138ac82003-04-22 18:44:01 +0000389static void set_nbxcfg(void)
390{
391 /* NBXCFG 0x50 - 0x53 */
392 /* f == 1111
393 * 0 == 0000
394 * 0 == 0000
395 * 0 == 0000
396 * 0 == 0000
397 * 1 == 0001
398 * 8 == 1000
399 * c == 1100
400 * SDRAM Row without ECC:
401 * row 0 == 1 No ECC
402 * row 1 == 1 No ECC
403 * row 2 == 1 No ECC
404 * row 3 == 1 No ECC
405 * row 4 == 1 No ECC
406 * row 5 == 1 No ECC
407 * row 6 == 1 No ECC
408 * row 7 == 1 No ECC
409 * Host Bus Fast Data Ready Enable == 0 Disabled
410 * IDSEL_REDIRECT == 0 (430TX compatibility disable?)
411 * WSC# Hanshake Disable == 0 enable (Use External IOAPIC)
412 * Host/DRAM Frequence == 00 100Mhz
413 * AGP to PCI Access Enable == 0 Disable
414 * PCI Agent to Aperture Access Disable == 0 Enable (Ignored)
415 * Aperture Access Global Enable == 0 Disable
416 * DRAM Data Integrity Mode == 11 (Error Checking/Correction)
417 * ECC Diagnostic Mode Enable == 0 Not Enabled
418 * MDA present == 0 Not Present
419 * USWC Write Post During During I/O Bridge Access Enable == 1 Enabled
Stefan Reinauer14e22772010-04-27 06:56:47 +0000420 * In Order Queue Depth (IQD) (RO) == ??
Eric Biedermanb138ac82003-04-22 18:44:01 +0000421 */
422 pcibios_write_config_dword(I440GX_BUS, I440GX_DEVFN, 0x50, 0xff00000c);
423}
424
425static void set_dramc(void)
426{
427 /* 0 == 0000
428 * 8 == 1000
429 * Not registered SDRAM
430 * refresh disabled
431 */
432 pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0x57, 0x8);
433}
434
435static void set_pam(void)
436{
437 /* PAM - Programmable Attribute Map Registers */
438 /* Ideally we want to enable all of these as DRAM and teach
439 * linux it is o.k. to use them...
440 */
441 pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0x59, 0x00);
442 pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0x5a, 0x00);
443 pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0x5b, 0x00);
444 pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0x5d, 0x00);
445 pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0x5e, 0x00);
446 pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0x5f, 0x00);
447}
448
449static void set_drb(void)
450{
451 /* DRB - DRAM Row Boundary Registers */
452 /* Conservative setting 8MB of ram on first DIMM... */
453 pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0x60, 0x01);
454 pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0x61, 0x01);
455 pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0x62, 0x01);
456 pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0x63, 0x01);
457 pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0x64, 0x01);
458 pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0x65, 0x01);
459 pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0x66, 0x01);
460 pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0x67, 0x01);
461}
462
463static void set_fdhc(void)
464{
465 pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0x68, 0x00);
466}
467static void set_mbsc(void)
468{
469 /* MBSC - Memory Buffer Strength Control */
470 /* 00c00003e820
471 * [47:44] 0 == 0000
472 * [43:40] 0 == 0000
473 * [39:36] c == 1100
474 * [35:32] 0 == 0000
475 * [31:28] 0 == 0000
476 * [27:24] 0 == 0000
477 * [23:20] 0 == 0000
478 * [19:16] 3 == 0011
479 * [15:12] e == 1110
480 * [11: 8] 8 == 1000
481 * [ 7: 4] 2 == 0010
482 * [ 3: 0] 0 == 0000
483 * MAA[14:0]#, WEA#, SRASA#, SCASA# Buffer Strengths == 3x
484 * MAB[14,13,10,12:11,9:0]#, WEB#, SRASB#, SCASB# Buffer Strengths == 3x
485 * MD[63:0]# Buffer Strength Control 2 == 3x
486 * MD[63:0]# Buffer Strength Control 1 == 3x
487 * MECC[7:0] Buffer Strength Control 2 == 3x
488 * MECC[7:0] Buffer Strength Control 1 == 3x
Stefan Reinauer14e22772010-04-27 06:56:47 +0000489 * CSB7# Buffer Strength == 3x
Eric Biedermanb138ac82003-04-22 18:44:01 +0000490 * CSA7# Buffer Strength == 3x
491 * CSB6# Buffer Strength == 3x
492 * CSA6# Buffer Strength == 3x
493 * CSA5#/CSB5# Buffer Strength == 2x
494 * CSA4#/CSB4# Buffer Strength == 2x
495 * CSA3#/CSB3# Buffer Strength == 2x
496 * CSA2#/CSB2# Buffer Strength == 2x
497 * CSA1#/CSB1# Buffer Strength == 2x
498 * CSA0#/CSB0# Buffer Strength == 2x
499 * DQMA5 Buffer Strength == 2x
500 * DQMA1 Buffer Strength == 3x
501 * DQMB5 Buffer Strength == 2x
502 * DQMB1 Buffer Strength == 2x
503 * DQMA[7:6,4:2,0] Buffer Strength == 3x
504 * GCKE Buffer Strength == 1x
505 * FENA Buffer Strength == 3x
506 */
507 pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0x69, 0xB3);
508 pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0x6a, 0xee);
509 pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0x6b, 0xff);
510 pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0x6c, 0xff);
511 pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0x6d, 0xff);
512 pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0x6e, 0x03);
513}
514
515static void set_smram(void)
516{
517 /* 0x72 SMRAM */
518 /* 1 == 0001
519 * a == 1010
520 * SMM Compatible base segment == 010 (Hardcoded value)
521 */
522}
523
524static void set_esramc(void)
525{
526 /* 0x73 ESMRAMC */
527}
528
529static void set_rps(void)
530{
531 /* RPS - Row Page Size Register */
532 /* 0x0055
533 * [15:12] 0 == 0000
534 * [11: 8] 0 == 0000
535 * [ 7: 4] 5 == 0101
536 * [ 3: 0] 5 == 0101
537 * DRB[0] == 4KB
538 * DRB[1] == 4KB
539 * DRB[2] == 4KB
540 * DRB[3] == 4KB
541 * DRB[4] == 2KB
542 * DRB[5] == 2KB
543 * DRB[6] == 2KB
544 * DRB[7] == 2KB
545 */
546 pcibios_write_config_word(I440GX_BUS, I440GX_DEVFN, 0x74, 0x5555);
547}
548
549static void set_sdramc(void)
550{
551 pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0x76, CAS_NB);
552}
553
554static void set_pgpol(void)
555{
556 /* PGPOL - Paging Policy Register */
557 /* 0xff07
558 * [15:12] f == 1111
559 * [11: 8] f == 1111
560 * [ 7: 4] 0 == 0000
561 * [ 3: 0] 7 == 0111
562 * row0 == 4banks
563 * row1 == 4banks
564 * row2 == 4banks
565 * row3 == 4banks
566 * row4 == 4banks
567 * row5 == 4banks
568 * row6 == 4banks
569 * row7 == 4banks
570 * Dram Idle Timer (DIT) == 32 clocks
571 */
572 pcibios_write_config_word(I440GX_BUS, I440GX_DEVFN, 0x78, 0xff07);
573}
574
575static void set_mbfs(void)
576{
577 /* MBFS - Memory Buffer Frequencey Select Register */
Stefan Reinauer14e22772010-04-27 06:56:47 +0000578 /* 0xffff7f
579 * [23:20] f == 1111
580 * [19:16] f == 1111
581 * [15:12] f == 1111
582 * [11: 8] f == 1111
583 * [ 7: 4] 7 == 0111
584 * [ 3: 0] f == 1111
Eric Biedermanb138ac82003-04-22 18:44:01 +0000585 * MAA[14:0], WEA#, SRASA#, SCASA# == 100Mhz Buffers Enabled
586 * MAB[14,13,10,12:11,9:0], WEB#, SRASB#, SCASB# == 100Mhz Buffers Enabled
587 * MD[63:0] Control 2 == 100 Mhz Buffer Enable
588 * MD[63:0] Control 1 == 100 Mhz B
589 * MECC[7:0] Control 2 == 100 Mhz B
590 *
591 */
592 pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0xca, 0xff);
593 pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0xcb, 0xff);
594 pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0xcc, 0x7f);
595}
596
597static void set_dwtc(void)
598{
599 /* DWTC - DRAM Write Thermal Throttle Control */
600 pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0xe0, 0xb4);
601 pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0xe1, 0xbe);
602 pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0xe2, 0xff);
603 pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0xe3, 0xd7);
604 pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0xe4, 0x97);
605 pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0xe5, 0x3e);
606 pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0xe6, 0x00);
607 pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0xe7, 0x80);
608}
609
610static void set_drtc(void)
611{
612 /* DRTC - DRAM Read Thermal Throttle Control */
613 pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0xe8, 0x2c);
614 pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0xe9, 0xd3);
615 pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0xea, 0xf7);
616 pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0xeb, 0xcf);
617 pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0xec, 0x9d);
618 pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0xed, 0x3e);
619 pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0xee, 0x00);
620 pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0xef, 0x00);
621}
622
623static void set_pmcr(void)
624{
Stefan Reinauer14e22772010-04-27 06:56:47 +0000625 /* PMCR -- BIOS sets 0x90 into it.
Eric Biedermanb138ac82003-04-22 18:44:01 +0000626 * 0x10 is REQUIRED.
627 * we have never used it. So why did this ever work?
628 */
629 pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0x7a, 0x90);
Stefan Reinauer14e22772010-04-27 06:56:47 +0000630
Eric Biedermanb138ac82003-04-22 18:44:01 +0000631}
632void sdram_set_registers(void)
633{
634 set_nbxcfg();
635 set_dramc();
636 set_pam();
637 set_drb();
638 set_fdhc();
639 set_mbsc();
640 set_smram();
641 set_esramc();
642 set_rps();
643 set_sdramc();
644 set_pgpol();
645 set_mbfs();
646 set_dwtc();
647 set_drtc();
648 set_pmcr();
649}
650
651int log2(int value)
652{
653 /* __builtin_bsr is a exactly equivalent to the x86 machine
Stefan Reinauer14e22772010-04-27 06:56:47 +0000654 * instruction with the exception that it returns -1
Eric Biedermanb138ac82003-04-22 18:44:01 +0000655 * when the value presented to it is zero.
656 * Otherwise __builtin_bsr returns the zero based index of
657 * the highest bit set.
658 */
659 return __builtin_bsr(value);
660}
661
662
663static void spd_set_drb(void)
664{
665 /*
666 * Effects: Uses serial presence detect to set the
667 * DRB registers which holds the ending memory address assigned
668 * to each DIMM.
669 */
670 unsigned end_of_memory;
671 unsigned device;
672 unsigned drb_reg;
Stefan Reinauer14e22772010-04-27 06:56:47 +0000673
Eric Biedermanb138ac82003-04-22 18:44:01 +0000674 end_of_memory = 0; /* in multiples of 8MiB */
675 device = SMBUS_MEM_DEVICE_START;
676 drb_reg = 0x60;
677 while (device <= SMBUS_MEM_DEVICE_END) {
678 unsigned side1_bits, side2_bits;
679 int byte, byte2;
680
681 side1_bits = side2_bits = -1;
682
683 /* rows */
684 byte = smbus_read_byte(device, 3);
685 if (byte >= 0) {
686 side1_bits += byte & 0xf;
687
688 /* columns */
689 byte = smbus_read_byte(device, 4);
690 side1_bits += byte & 0xf;
691
692 /* banks */
693 byte = smbus_read_byte(device, 17);
694 side1_bits += log2(byte);
695
696 /* Get the moduel data width and convert it to a power of two */
697 /* low byte */
698 byte = smbus_read_byte(device, 6);
699
700 /* high byte */
701 byte2 = smbus_read_byte(device, 7);
702#if HAVE_CAST_SUPPORT
703 side1_bits += log2((((unsigned long)byte2 << 8)| byte));
704#else
705 side1_bits += log2((byte2 << 8) | byte);
706#endif
Stefan Reinauer14e22772010-04-27 06:56:47 +0000707
Eric Biedermanb138ac82003-04-22 18:44:01 +0000708 /* now I have the ram size in bits as a power of two (less 1) */
709 /* Make it mulitples of 8MB */
710 side1_bits -= 25;
Stefan Reinauer14e22772010-04-27 06:56:47 +0000711
Eric Biedermanb138ac82003-04-22 18:44:01 +0000712 /* side two */
Stefan Reinauer14e22772010-04-27 06:56:47 +0000713
Eric Biedermanb138ac82003-04-22 18:44:01 +0000714 /* number of physical banks */
715 byte = smbus_read_byte(device, 5);
716 if (byte > 1) {
717 /* for now only handle the symmetrical case */
718 side2_bits = side1_bits;
719 }
720 }
721
722 /* Compute the end address for the DRB register */
723 /* Only process dimms < 2GB (2^8 * 8MB) */
724 if (side1_bits < 8) {
725 end_of_memory += (1 << side1_bits);
726 }
727#if HAVE_STRING_SUPPORT
728 print_debug("end_of_memory: "); print_debug_hex32(end_of_memory); print_debug("\n");
729#endif
730 pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, drb_reg, end_of_memory);
731
732 if (side2_bits < 8 ) {
733 end_of_memory += (1 << side2_bits);
734 }
735#if HAVE_STRING_SUPPORT
736 print_debug("end_of_memory: "); print_debug_hex32(end_of_memory); print_debug("\n");
737#endif
738 pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, drb_reg +1, end_of_memory);
739
740 drb_reg += 2;
741 device += SMBUS_MEM_DEVICE_INC;
742 }
743}
744
745void sdram_no_memory(void)
746{
747#if HAVE_STRING_SUPPORT
748 print_err("No memory!!\n");
749#endif
750 while(1) ;
751}
752
753static void spd_set_dramc(void)
754{
755 /*
756 * Effects: Uses serial presence detect to set the
757 * DRAMC register, which records if ram is registerd or not,
758 * and controls the refresh rate.
759 * The refresh rate is not set here, as memory refresh
760 * cannot be enbaled until after memory is initialized.
761 * see spd_enable_refresh.
762 */
763 /* auto detect if ram is registered or not. */
764 /* The DRAMC register also contorls the refresh rate but we can't
765 * set that here because we must leave refresh disabled.
766 * see: spd_enable_refresh
767 */
768 /* Find the first dimm and assume the rest are the same */
769 /* FIXME Check for illegal/unsupported ram configurations and abort */
770 unsigned device;
771 int byte;
772 unsigned dramc;
773 byte = -1;
774 device = SMBUS_MEM_DEVICE_START;
775
776 while ((byte < 0) && (device <= SMBUS_MEM_DEVICE_END)) {
777 byte = smbus_read_byte(device, 21);
778 device += SMBUS_MEM_DEVICE_INC;
779 }
780 if (byte < 0) {
781 /* We couldn't find anything we must have no memory */
782 sdram_no_memory();
783 }
784 dramc = 0x8;
785 if ((byte & 0x12) != 0) {
Stefan Reinauer14e22772010-04-27 06:56:47 +0000786 /* this is a registered part.
787 * observation: for register parts, BIOS zeros (!)
Eric Biedermanb138ac82003-04-22 18:44:01 +0000788 * registers CA-CC. This has an undocumented meaning.
789 */
790 /* But it does make sense the oppisite of registered
791 * sdram is buffered and 0xca - 0xcc control the buffers.
792 * Clearing them aparently disables them.
793 */
794 pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0xca, 0);
795 pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0xcb, 0);
796 pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0xcc, 0);
797 dramc = 0x10;
798 }
799 pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0x57, dramc);
800}
801
802static void spd_enable_refresh(void)
803{
804 /*
805 * Effects: Uses serial presence detect to set the
806 * refresh rate in the DRAMC register.
807 * see spd_set_dramc for the other values.
808 * FIXME: Check for illegal/unsupported ram configurations and abort
809 */
810#if HAVE_STATIC_ARRAY_SUPPORT
811 static const unsigned char refresh_rates[] = {
812 0x01, /* Normal 15.625 us -> 15.6 us */
813 0x05, /* Reduced(.25X) 3.9 us -> 7.8 us */
814 0x05, /* Reduced(.5X) 7.8 us -> 7.8 us */
815 0x02, /* Extended(2x) 31.3 us -> 31.2 us */
816 0x03, /* Extended(4x) 62.5 us -> 62.4 us */
817 0x04, /* Extended(8x) 125 us -> 124.8 us */
818 };
819#endif
820 /* Find the first dimm and assume the rest are the same */
821 int status;
822 int byte;
823 unsigned device;
824 unsigned refresh_rate;
825 byte = -1;
826 status = -1;
827 device = SMBUS_MEM_DEVICE_START;
828 while ((byte < 0) && (device <= SMBUS_MEM_DEVICE_END)) {
829 byte = smbus_read_byte(device, 12);
830 device += SMBUS_MEM_DEVICE_INC;
831 }
832 if (byte < 0) {
833 /* We couldn't find anything we must have no memory */
834 sdram_no_memory();
835 }
836 byte &= 0x7f;
837 /* Default refresh rate be conservative */
Stefan Reinauer14e22772010-04-27 06:56:47 +0000838 refresh_rate = 5;
Eric Biedermanb138ac82003-04-22 18:44:01 +0000839 /* see if the ram refresh is a supported one */
840 if (byte < 6) {
841#if HAVE_STATIC_ARRAY_SUPPORT
842 refresh_rate = refresh_rates[byte];
843#endif
844 }
845 byte = pcibios_read_config_byte(I440GX_BUS, I440GX_DEVFN, 0x57);
846 byte &= 0xf8;
847 byte |= refresh_rate;
848 pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0x57, byte);
849}
850
851static void spd_set_sdramc(void)
852{
853 return;
854}
855
856static void spd_set_rps(void)
857{
858 /*
Stefan Reinauer14e22772010-04-27 06:56:47 +0000859 * Effects: Uses serial presence detect to set the row size
Eric Biedermanb138ac82003-04-22 18:44:01 +0000860 * on a given DIMM
861 * FIXME: Check for illegal/unsupported ram configurations and abort
862 */
863 /* The RPS register holds the size of a ``page'' of DRAM on each DIMM */
864 unsigned page_sizes;
865 unsigned index;
866 unsigned device;
867 unsigned char dramc;
868 /* default all page sizes to 2KB */
869 page_sizes = 0;
870 index = 0;
871 device = SMBUS_MEM_DEVICE_START;
872 for(; device <= SMBUS_MEM_DEVICE_END; index += 4, device += SMBUS_MEM_DEVICE_INC) {
873 unsigned int status;
874 unsigned int byte;
875 int page_size;
876
877 byte = smbus_read_byte(device, 3);
878 if (byte < 0) continue;
879
880 /* I now have the row page size as a power of 2 */
881 page_size = byte & 0xf;
882 /* make it in multiples of 2Kb */
883 page_size -= 11;
Stefan Reinauer14e22772010-04-27 06:56:47 +0000884
Eric Biedermanb138ac82003-04-22 18:44:01 +0000885 if (page_size <= 0) continue;
Stefan Reinauer14e22772010-04-27 06:56:47 +0000886
Eric Biedermanb138ac82003-04-22 18:44:01 +0000887 /* FIXME: do something with page sizes greather than 8KB!! */
888 page_sizes |= (page_size << index);
Stefan Reinauer14e22772010-04-27 06:56:47 +0000889
Eric Biedermanb138ac82003-04-22 18:44:01 +0000890 /* side two */
891 byte = smbus_read_byte(device, 5);
892 if (byte <= 1) continue;
Stefan Reinauer14e22772010-04-27 06:56:47 +0000893
Eric Biedermanb138ac82003-04-22 18:44:01 +0000894 /* For now only handle the symmetrical case */
895 page_sizes |= (page_size << (index +2));
896 }
897 /* next block is for Ron's attempt to get registered to work. */
898 /* we have just verified that we have to have this code. It appears that
899 * the registered SDRAMs do indeed set the RPS wrong. sheesh.
900 */
Stefan Reinauer14e22772010-04-27 06:56:47 +0000901 /* at this point, page_sizes holds the RPS for all ram.
902 * we have verified that for registered DRAM the values are
Eric Biedermanb138ac82003-04-22 18:44:01 +0000903 * 1/2 the size they should be. So we test for registered
Stefan Reinauer14e22772010-04-27 06:56:47 +0000904 * and then double the sizes if needed.
Eric Biedermanb138ac82003-04-22 18:44:01 +0000905 */
906
907 dramc = pcibios_read_config_byte(I440GX_BUS, I440GX_DEVFN, 0x57);
908 if (dramc & 0x10) {
909 /* registered */
910
911 /* BIOS makes weird page size for registered! */
Stefan Reinauer14e22772010-04-27 06:56:47 +0000912 /* what we have found is you need to set the EVEN banks to
913 * twice the size. Fortunately there is a very easy way to
914 * do this. First, read the WORD value of register 0x74.
Eric Biedermanb138ac82003-04-22 18:44:01 +0000915 */
916 page_sizes += 0x1111;
917 }
918
919 pcibios_write_config_word(I440GX_BUS, I440GX_DEVFN, 0x74, page_sizes);
920}
921
922static void spd_set_pgpol(void)
923{
924 /*
925 * Effects: Uses serial presence detect to set the number of banks
926 * on a given DIMM
927 * FIXME: Check for illegal/unsupported ram configurations and abort
928 */
929 /* The PGPOL register stores the number of logical banks per DIMM,
930 * and number of clocks the DRAM controller waits in the idle
931 * state.
932 */
933 unsigned device;
934 unsigned bank_sizes;
935 unsigned bank;
936 unsigned reg;
937 /* default all bank counts 2 */
938 bank_sizes = 0;
939 bank = 0;
940 device = SMBUS_MEM_DEVICE_START;
Stefan Reinauer14e22772010-04-27 06:56:47 +0000941 for(; device <= SMBUS_MEM_DEVICE_END;
942 bank += 2, device += SMBUS_MEM_DEVICE_INC) {
Eric Biedermanb138ac82003-04-22 18:44:01 +0000943 int byte;
944
945 /* logical banks */
946 byte = smbus_read_byte(device, 17);
947 if (byte < 0) continue;
948 if (byte < 4) continue;
949 bank_sizes |= (1 << bank);
Stefan Reinauer14e22772010-04-27 06:56:47 +0000950
Eric Biedermanb138ac82003-04-22 18:44:01 +0000951 /* side 2 */
952 /* Number of physical banks */
953 byte = smbus_read_byte(device, 5);
954 if (byte <= 1) continue;
955 /* for now only handle the symmetrical case */
956 bank_sizes |= (1 << (bank +1));
957 }
958 reg = bank_sizes << 8;
959 reg |= 0x7; /* 32 clocks idle time */
960 pcibios_write_config_word(I440GX_BUS, I440GX_DEVFN, 0x78, reg);
961}
962
963static void spd_set_nbxcfg(void)
964{
965 /*
966 * Effects: Uses serial presence detect to set the
967 * ECC support flags in the NBXCFG register
968 * FIXME: Check for illegal/unsupported ram configurations and abort
969 */
970 unsigned reg;
971 unsigned index;
972 unsigned device;
973
974 /* Say all dimms have no ECC support */
975 reg = 0xff;
976 index = 0;
Stefan Reinauer14e22772010-04-27 06:56:47 +0000977
Eric Biedermanb138ac82003-04-22 18:44:01 +0000978 device = SMBUS_MEM_DEVICE_START;
979 for(; device <= SMBUS_MEM_DEVICE_END; index += 2, device += SMBUS_MEM_DEVICE_INC) {
980 int byte;
981
982 byte = smbus_read_byte(device, 11);
983 if (byte < 0) continue;
Stefan Reinauer14e22772010-04-27 06:56:47 +0000984#if !USE_ECC
Eric Biedermanb138ac82003-04-22 18:44:01 +0000985 byte = 0; /* Disable ECC */
986#endif
987 /* 0 == None, 1 == Parity, 2 == ECC */
988 if (byte != 2) continue;
989 reg ^= (1 << index);
990
991 /* side two */
992 /* number of physical banks */
993 byte = smbus_read_byte(device, 5);
994 if (byte <= 1) continue;
995 /* There is only the symmetrical case */
996 reg ^= (1 << (index +1));
997 }
998 pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0x53, reg);
999 /* Now see if reg is 0xff. If it is we are done. If not,
1000 * we need to set 0x18 into regster 0x50.l
1001 * we will do this in two steps, first or in 0x80 to 0x50.b,
1002 * then or in 0x1 to 0x51.b
1003 */
1004#if HAVE_STRING_SUPPORT
1005 print_debug("spd_set_nbxcfg reg="); print_debug_hex8(reg); print_debug("\n");
1006#endif
1007 if (reg != 0xff) {
1008 unsigned char byte;
1009 byte = pcibios_read_config_byte(I440GX_BUS, I440GX_DEVFN, 0x50);
1010 byte |= 0x80;
1011 pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0x50, byte);
1012 byte = pcibios_read_config_byte(I440GX_BUS, I440GX_DEVFN, 0x51);
1013 byte |= 1;
1014 pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0x51, byte);
1015 /* try this.
1016 * We should be setting bit 2 in register 76 and we're not
1017 * technically we should see if CL=2 for the ram,
Stefan Reinauer14e22772010-04-27 06:56:47 +00001018 * but registered is so screwed up that it's kind of a lost
Eric Biedermanb138ac82003-04-22 18:44:01 +00001019 * cause.
1020 */
1021 byte = pcibios_read_config_byte(I440GX_BUS, I440GX_DEVFN, 0x76);
1022 byte |= 4;
1023 pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0x76, byte);
1024#if HAVE_STRING_SUPPORT
1025 print_debug("spd_set_nbxcfg 0x76.b="); print_debug_hex8(byte); print_debug("\n");
1026#endif
1027 }
1028}
1029
1030void sdram_set_spd_registers(void)
1031{
1032 spd_set_drb();
1033 spd_set_dramc();
1034 spd_set_rps();
1035 spd_set_sdramc();
1036 spd_set_pgpol();
1037 spd_set_nbxcfg();
1038}
1039
1040void sdram_first_normal_reference(void)
1041{
1042 return;
1043}
1044
1045void sdram_special_finishup(void)
1046{
1047 return;
1048}
1049
1050static void set_ram_command(unsigned command)
1051{
1052 unsigned char byte;
1053 command &= 0x7;
1054 byte = pcibios_read_config_byte(I440GX_BUS, I440GX_DEVFN, 0x76);
1055 byte &= 0x1f;
1056 byte |= (command << 5);
1057 pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0x76, byte);
1058#if HAVE_STRING_SUPPORT
1059 print_debug("set_ram_command 0x76.b="); print_debug_hex8(byte); print_debug("\n");
1060#endif
1061}
1062
1063#define RAM_COMMAND_NONE 0x0
1064#define RAM_COMMAND_NOOP 0x1
1065#define RAM_COMMAND_PRECHARGE 0x2
1066#define RAM_COMMAND_MRS 0x3
1067#define RAM_COMMAND_CBR 0x4
1068
1069void sdram_set_command_none(void)
1070{
1071 set_ram_command(RAM_COMMAND_NONE);
1072}
1073void sdram_set_command_noop(void)
1074{
1075 set_ram_command(RAM_COMMAND_NOOP);
1076}
1077void sdram_set_command_precharge(void)
1078{
1079 set_ram_command(RAM_COMMAND_PRECHARGE);
1080}
1081
1082static unsigned long dimm_base(int n)
1083{
1084 unsigned char byte;
1085 unsigned long result;
1086 if (n == 0) {
1087 return 0;
1088 }
1089
1090 byte = pcibios_read_config_byte(I440GX_BUS, I440GX_DEVFN, 0x60 + (n - 1));
1091 result = byte;
1092 result <<= 23;
1093 return result;
1094}
1095
1096static void dimms_read(unsigned long offset)
1097{
1098 int i;
1099 for(i = 0; i < 8; i++) {
1100 unsigned long dummy;
Stefan Reinauer14e22772010-04-27 06:56:47 +00001101 unsigned long addr;
Eric Biedermanb138ac82003-04-22 18:44:01 +00001102 unsigned long next_base;
1103
1104 next_base = dimm_base(i +1);
1105 addr = dimm_base(i);
1106 if (addr == next_base) {
1107 continue;
1108 }
1109 addr += offset;
1110#if HAVE_STRING_SUPPORT
Stefan Reinauer14e22772010-04-27 06:56:47 +00001111 print_debug("Reading ");
1112 print_debug_hex32(addr);
Eric Biedermanb138ac82003-04-22 18:44:01 +00001113 print_debug("\n");
1114#endif
1115#if HAVE_POINTER_SUPPORT
Eric Biederman6aa31cc2003-06-10 21:22:07 +00001116#if HAVE_MACRO_ARG_SUPPORT
Eric Biedermanb138ac82003-04-22 18:44:01 +00001117 dummy = RAM(unsigned long, addr);
Eric Biederman6aa31cc2003-06-10 21:22:07 +00001118#else
1119 dummy = *((volatile unsigned long *)(addr));
1120#endif
Eric Biedermanb138ac82003-04-22 18:44:01 +00001121#endif
1122#if HAVE_STRING_SUPPORT
Stefan Reinauer14e22772010-04-27 06:56:47 +00001123 print_debug("Reading ");
1124 print_debug_hex32(addr ^ 0xddf8);
Eric Biedermanb138ac82003-04-22 18:44:01 +00001125 print_debug("\n");
1126#endif
1127#if HAVE_POINTER_SUPPORT
Eric Biederman6aa31cc2003-06-10 21:22:07 +00001128#if HAVE_MACRO_ARG_SUPPORT
Eric Biedermanb138ac82003-04-22 18:44:01 +00001129 dummy = RAM(unsigned long, addr ^ 0xdff8);
Eric Biederman6aa31cc2003-06-10 21:22:07 +00001130#else
1131 dummy = *((volatile unsigned long *)(addr ^ 0xdff8));
1132#endif
Eric Biedermanb138ac82003-04-22 18:44:01 +00001133#endif
1134#if HAVE_STRING_SUPPORT
Stefan Reinauer14e22772010-04-27 06:56:47 +00001135 print_debug("Read ");
1136 print_debug_hex32(addr);
1137 print_debug_hex32(addr ^ 0xddf8);
Eric Biedermanb138ac82003-04-22 18:44:01 +00001138 print_debug("\n");
1139#endif
1140 }
1141}
1142
1143void sdram_set_command_cbr(void)
1144{
1145 set_ram_command(RAM_COMMAND_CBR);
1146}
1147
1148void sdram_assert_command(void)
1149{
1150 dimms_read(0x400);
1151}
1152
1153void sdram_set_mode_register(void)
1154{
1155 unsigned char byte;
1156 unsigned cas_mode;
1157 set_ram_command(RAM_COMMAND_MRS);
1158 byte = pcibios_read_config_byte(I440GX_BUS, I440GX_DEVFN, 0x76);
1159 cas_mode = byte & 0x4;
1160 cas_mode ^= 4;
1161 cas_mode <<= 2;
1162 cas_mode |= 0x2a;
1163 cas_mode <<= 3;
1164 dimms_read(cas_mode);
1165}
1166
1167void sdram_enable_refresh(void)
1168{
1169 spd_enable_refresh();
1170}
1171
1172
1173unsigned long sdram_get_ecc_size_bytes(void)
1174{
1175 unsigned char byte;
1176 unsigned long size;
1177 /* FIXME handle the no ram case. */
1178 /* Read the RAM SIZE */
1179 byte = pcibios_read_config_byte(I440GX_BUS, I440GX_DEVFN, 0x67);
1180 /* Convert it to bytes */
1181 size = byte;
1182 size <<= 23;
1183#if !USE_ECC
1184 size = 0;
1185#endif
1186 return size;
1187}
1188
1189/* Dummy udelay code acting as a place holder... */
1190void udelay(int count)
1191{
1192 int i;
1193 i = 5;
1194}
1195
1196void sdram_enable(void)
1197{
1198#if HAVE_STRING_SUPPORT
1199 print_debug("Ram Enable 1\n");
1200#endif
1201
1202 /* noop command */
1203 sdram_set_command_noop();
1204 udelay(200);
1205 sdram_assert_command();
1206
1207 /* Precharge all */
1208 sdram_set_command_precharge();
1209 sdram_assert_command();
1210
1211 /* wait until the all banks idle state... */
1212#if HAVE_STRING_SUPPORT
1213 print_debug("Ram Enable 2\n");
1214#endif
Stefan Reinauer14e22772010-04-27 06:56:47 +00001215
Eric Biedermanb138ac82003-04-22 18:44:01 +00001216 /* Now we need 8 AUTO REFRESH / CBR cycles to be performed */
Stefan Reinauer14e22772010-04-27 06:56:47 +00001217
Eric Biedermanb138ac82003-04-22 18:44:01 +00001218 sdram_set_command_cbr();
1219 sdram_assert_command();
1220 sdram_assert_command();
1221 sdram_assert_command();
1222 sdram_assert_command();
1223 sdram_assert_command();
1224 sdram_assert_command();
1225 sdram_assert_command();
1226 sdram_assert_command();
Stefan Reinauer14e22772010-04-27 06:56:47 +00001227
Eric Biedermanb138ac82003-04-22 18:44:01 +00001228#if HAVE_STRING_SUPPORT
1229 print_debug("Ram Enable 3\n");
1230#endif
Stefan Reinauer14e22772010-04-27 06:56:47 +00001231
Eric Biedermanb138ac82003-04-22 18:44:01 +00001232 /* mode register set */
1233 sdram_set_mode_register();
1234 /* MAx[14:0] lines,
1235 * MAx[2:0 ] 010 == burst mode of 4
1236 * MAx[3:3 ] 1 == interleave wrap type
1237 * MAx[4:4 ] == CAS# latency bit
1238 * MAx[6:5 ] == 01
1239 * MAx[12:7] == 0
1240 */
1241
1242#if HAVE_STRING_SUPPORT
1243 print_debug("Ram Enable 4\n");
1244#endif
1245
1246 /* normal operation */
1247 sdram_set_command_none();
Stefan Reinauer14e22772010-04-27 06:56:47 +00001248
Eric Biedermanb138ac82003-04-22 18:44:01 +00001249#if HAVE_STRING_SUPPORT
1250 print_debug("Ram Enable 5\n");
1251#endif
1252}
1253
1254/* Setup SDRAM */
1255void sdram_initialize(void)
1256{
1257#if HAVE_STRING_SUPPORT
1258 print_debug("Ram1\n");
1259#endif
1260 /* Set the registers we can set once to reasonable values */
1261 sdram_set_registers();
1262
1263#if HAVE_STRING_SUPPORT
1264 print_debug("Ram2\n");
1265#endif
1266 /* Now setup those things we can auto detect */
1267 sdram_set_spd_registers();
1268
1269#if HAVE_STRING_SUPPORT
1270 print_debug("Ram3\n");
1271#endif
1272 /* Now that everything is setup enable the SDRAM.
Stefan Reinauer14e22772010-04-27 06:56:47 +00001273 * Some chipsets do the work for use while on others
Eric Biedermanb138ac82003-04-22 18:44:01 +00001274 * we need to it by hand.
1275 */
1276 sdram_enable();
1277
1278#if HAVE_STRING_SUPPORT
1279 print_debug("Ram4\n");
1280#endif
1281 sdram_first_normal_reference();
1282
1283#if HAVE_STRING_SUPPORT
1284 print_debug("Ram5\n");
1285#endif
1286 sdram_enable_refresh();
1287 sdram_special_finishup();
1288
1289#if HAVE_STRING_SUPPORT
1290 print_debug("Ram6\n");
1291#endif
1292}