From be3ebbe61f93601fe2c05f8df343fd3a5223cccf Mon Sep 17 00:00:00 2001 From: "Ronald G. Minnich" Date: Sat, 3 Nov 2001 00:22:28 +0000 Subject: [PATCH] Support for the rcn dc1100s mainboard. The 694 files are probably wrong. --- src/mainboard/rcn/dc1100s/Config | 17 + src/mainboard/rcn/dc1100s/Example.config | 21 ++ src/mainboard/rcn/dc1100s/mainboard.c | 6 + src/northbridge/via/vt694/Config | 1 + src/northbridge/via/vt694/afteram.inc | 50 +++ src/northbridge/via/vt694/ipl.S | 385 +++++++++++++++++++++++ src/northbridge/via/vt694/northbridge.c | 74 +++++ src/northbridge/via/vt694/raminit.inc | 171 ++++++++++ src/northbridge/via/vt694/raminitspd.inc | 382 ++++++++++++++++++++++ 9 files changed, 1107 insertions(+) create mode 100644 src/mainboard/rcn/dc1100s/Config create mode 100644 src/mainboard/rcn/dc1100s/Example.config create mode 100644 src/mainboard/rcn/dc1100s/mainboard.c create mode 100644 src/northbridge/via/vt694/Config create mode 100644 src/northbridge/via/vt694/afteram.inc create mode 100644 src/northbridge/via/vt694/ipl.S create mode 100644 src/northbridge/via/vt694/northbridge.c create mode 100644 src/northbridge/via/vt694/raminit.inc create mode 100644 src/northbridge/via/vt694/raminitspd.inc diff --git a/src/mainboard/rcn/dc1100s/Config b/src/mainboard/rcn/dc1100s/Config new file mode 100644 index 0000000000..a7b8818250 --- /dev/null +++ b/src/mainboard/rcn/dc1100s/Config @@ -0,0 +1,17 @@ +arch i386 +mainboardinit cpu/i386/entry16.inc +ldscript cpu/i386/entry16.lds + +mainboardinit superio/via/vt82c686/setup_serial.inc +mainboardinit pc80/serial.inc +northbridge via/vt694 +southbridge via/vt82c686 +superio via/vt82c686 +mainboardinit cpu/p6/earlymtrr.inc + +option ENABLE_FIXED_AND_VARIABLE_MTRRS +option SUPERIO_DEVFN=0x88 +object mainboard.o +keyboard pc80 +cpu p5 +cpu p6 diff --git a/src/mainboard/rcn/dc1100s/Example.config b/src/mainboard/rcn/dc1100s/Example.config new file mode 100644 index 0000000000..d12b82300b --- /dev/null +++ b/src/mainboard/rcn/dc1100s/Example.config @@ -0,0 +1,21 @@ + +# This will make a target directory of ./via +target dc1100s + +# VIA test mainboard +mainboard rcn/dc1100s + +option USE_DOC_MIL +docipl northbridge/via/vt694/ipl.S +# Enable Serial Console for debugging +option SERIAL_CONSOLE + +# Enable MicroCode update and L2 Cache init for PII and PIII +option UPDATE_MICROCODE +option CONFIGURE_L2_CACHE + +# Path to your kernel (vmlinux) +linux ~/src/bios/linux-2.4.0-rcn + +option CMD_LINE='"root=/dev/hda1 single"' + diff --git a/src/mainboard/rcn/dc1100s/mainboard.c b/src/mainboard/rcn/dc1100s/mainboard.c new file mode 100644 index 0000000000..dc2118cfc9 --- /dev/null +++ b/src/mainboard/rcn/dc1100s/mainboard.c @@ -0,0 +1,6 @@ +void +mainboard_fixup() +{ + void southbridge_fixup(void); + southbridge_fixup(); +} diff --git a/src/northbridge/via/vt694/Config b/src/northbridge/via/vt694/Config new file mode 100644 index 0000000000..5191cb272f --- /dev/null +++ b/src/northbridge/via/vt694/Config @@ -0,0 +1 @@ +object northbridge.o diff --git a/src/northbridge/via/vt694/afteram.inc b/src/northbridge/via/vt694/afteram.inc new file mode 100644 index 0000000000..a641f923a5 --- /dev/null +++ b/src/northbridge/via/vt694/afteram.inc @@ -0,0 +1,50 @@ +/* + v1.0: 02/15/2001: Program procedure to make workable and stable register settings: + (1) Initial registers: 0x40:0x48, 0x41:0x4d, 0x43:0x44, 0x44:0x04, 0x83:0x02, 0x3e:0x0c + v1.1: 02/15/2001: + (1) Initial registers: To add 0x3e:0x0c + (2) After initial: To add bus0, devfn0 0x84:0xc0 + v1.2: 02/15/2001: + To set 0x13 register to 0xd8 value, thus it won't hang the system if enable graphic aperture(0x88 bit 2). But + I am not sure if it would take effect for graphic device. According to the result, the system won't hang and check + the register setting, that's right, they do set those values except the aperture base(0x13) has been changed to 0x84 + which means the pci configure does the resource allocation. But why it won't start up the monitor??? +*/ + +jmp ptp_afteram_set_registers + +ptp_afteram_table: + .byte 0x40, 0x48 + .byte 0x41, 0x4d + .byte 0x43, 0x44 + .byte 0x44, 0x04 + .byte 0x83, 0x02 + .byte 0x3e, 0x0c + .byte 0x0 /* end of table */ + +ptp_afteram_set_registers: + /* standard x86 loop on table until done code */ + /* assumes that: devfn is 8 (safe on anything we've seen) */ + /* which means addresses are a byte */ + /* address is first, then data */ + movl $ptp_afteram_table, %esi +1: + /* zero out eax. This is a must right here. */ + xor %eax, %eax + movb (%esi), %al + testb %al, %al + jz done_ptp_afteram_set_registers + inc %esi + orl $0x0800, %eax + movb (%esi), %dl + PCI_WRITE_CONFIG_BYTE + inc %esi + jmp 1b + +done_ptp_afteram_set_registers: + CS_WRITE($0x13, $0xd8) + CS_WRITE($0x84, $0xc0) + CS_WRITE($0x80, $0x0f) + CS_WRITE($0x88, $0x02) + intel_chip_post_macro(0x99) + diff --git a/src/northbridge/via/vt694/ipl.S b/src/northbridge/via/vt694/ipl.S new file mode 100644 index 0000000000..bf0b7c946b --- /dev/null +++ b/src/northbridge/via/vt694/ipl.S @@ -0,0 +1,385 @@ +#include "asm.h" +//#include +#include "intel.h" +/* + */ + +#define DOC_WIN_SEG 0xfe00 +#define DOC_STACK_SEG 0x0400 +#define SPL_RAM_SEG 0x8000 + +#define DOC_SPL_START_BLK 2 /* 0,1 for IPL */ +#define DOC_SPL_SIZE_IN_PAGE 252 /* 1 page = 512 bytes, total 63kB */ + +/* wow, the usual way to to this hurts. So we do it our way: + * 32-bit test not needed. + */ +/*#include */ +.org 0x0 +.code16 +_start: jmp _realstart + + +/* initialize registers */ +#define REG(a) a&0xfc, (a&0x3)|4 +register_table: + .byte REG(0x78), 0x01 + .byte REG(0x68), 0x00 + .byte REG(0x6b), 0x00 + .byte REG(0x58), 0x88 + .byte REG(0x59), 0x88 + .byte REG(0x5a), 0x08 + .byte REG(0x5b), 0x10 + .byte REG(0x5c), 0x10 + .byte REG(0x5d), 0x10 + .byte REG(0x5e), 0x10 + .byte REG(0x5f), 0x10 + .byte REG(0x56), 0x10 + .byte REG(0x57), 0x10 + .byte REG(0x60), 0xff + .byte REG(0x64), 0xee + .byte REG(0x65), 0xee + .byte REG(0x66), 0xee + .byte REG(0x69), 0x04 + .byte REG(0x6a), 0x00 + .byte REG(0x6c), 0x00 + .byte REG(0x6d), 0x37 + // This extra set is redundant, but needed below. + // LEAVE IT HERE. + .byte REG(0x6c), 0x0 + .byte 0x0 +_realstart: +// movb $0xaa,%al +// outb %al,$0x80 + cli + movw %cs, %ax + movw %ax, %ds + + movl $0x80008840, %eax + movw $0x0cf8, %dx + outl %eax,%dx + movb $0xfc,%dl + movb $0x54,%al + outb %al,%dx +// inl %dx, %eax +// orw $0x7f10, %ax +// outw %ax,%dx + +//.code32 +#define loop200 $0x5000 +#define loop100 $0x2500 +movl $0x80000000,%esp +ram_set_registers: + movw $register_table, %si + cld +1: + movl %esp, %eax + orb (%si), %al + testb %al, %al + jz done_ram_set_registers + andb $0xf8, %dl + outl %eax, %dx + + inc %si + orb (%si), %dl + inc %si + movb (%si), %al + outb %al, %dx +// PCI_WRITE_CONFIG_BYTE + inc %si + jmp 1b +// movb $0xbb,%al +// outb %al,$0x80 + +done_ram_set_registers: + xorw %si, %si +// movl $0x4000000, %edi +/* begin to initialize*/ + // I forget why we need this, but we do + movl $0xa55a5aa5, %ecx + movl %ecx, (%si) + +// mov %ecx, (%edi) +// REMEMBER: 0xcf8 was set to 0x8000006c above. No need to set +// again! +// Also, remember: %edx has 0xcfc from the above loop! +// that is the correct value! +/* set NOP*/ +#define WRITE_6c(unused,val) movb val, %al ; outb %al, %dx + WRITE_6c($0x6C, $0x01) + +/* wait 200us*/ + // You need to do the memory reference. That causes the nop cycle. + movw (%si), %cx +// mov (%edi), %ecx + DELAY(loop200) + +/* set precharge */ + WRITE_6c($0x6C, $0x02) + +/* dummy reads*/ + movw (%si), %cx +// mov (%edi), %ecx + +/* set CBR*/ + WRITE_6c($0x6C, $0x04) + +/* do 8 reads and wait 100us between each - from via*/ + + movb $8, %bl +eightreads: + movw (%si), %cx +// mov (%edi), %ecx + DELAY(loop100) + dec %bl + cmpb $0, %bl + ja eightreads + +/* set MRS*/ + // 0x150 is cas2. We are now using 0x1d0, which is cas3 + WRITE_6c($0x6c, $0x03) + + movw $0x1d0, %di + movl (%di), %ecx +// movl $0x40001d0, %ecx +// movl (%ecx), %ecx + +/* set to normal mode */ + WRITE_6c($0x6C, $0x00) + + movl $0x55aa55aa, %ecx + movl %ecx, (%si) + movl (%si), %ecx + + // Set the refresh rate. + movb $0x68, %al + movb $0xf8, %dl + outl %eax, %dx + addw $7, %dx + movb $0x65, %al + outb %al, %dx + //CS_WRITE($0x6A, $0x65) + // enable multi-page open + inc %dl + movb $1, %al + outb %al, %dx + //CS_WRITE($0x6B, $0x01) +// movb $0xcc,%al +// outb %al,$0x80 + + /* now for flash ... */ + /* NOTE: MUST NOT DESTROY %ecx! */ + /* INPUT: %al, the register. %ecx, the write data */ + /* Following code courtesy Ollie Lho: */ +/* + * ipl.S: Initial Program Loader (IPL) for SiS 630 and M-System DoC Millennium + * + * + * Copyright 2000 Silicon Integrated Systems Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * + * Reference: + * 1. SiS 630 Specification + * 2. System Management Bus Specification Rev 1.1 + * 3. PC SDRAM Serial Presence Detect (SPD) Specification Rev 1.2B + * 4. Booting From the DiskOnChip Millennium, M-Systems Application Note Ap-DOC-044 + * APR-2000, 93-SR-001-44-7L REV. 1.0 + * + * $Id$ + */ +// .code16 +#define DOC_WIN_SEG 0xfe00 +#define DOC_STACK 0x04000 +#define SPL_RAM 0x80000 + +#define DOC_SPL_START_BLK 2 /* 0,1 for IPL */ +#define DOC_SPL_SIZE_IN_PAGE 252 /* 1 page = 512 bytes, total 63kB */ + +ipl_start: +//#if 0 + /* stack and es already set. */ + /* O.K. we have DRAM now, so set up STACK for CALL/RET */ + movw $DOC_STACK_SEG, %ax + movw %ax, %ss + movw $SPL_RAM_SEG, %ax + movw %ax, %es +// movl $DOC_STACK_SEG, %esp # set %sp +//#endif + /* NOTE: in ollie's original code, %ds was at 0xfe00, i.e. + * 0xfe000, i.e. base of DoC. We have to adjust for that when + * we set %edi and %esi + */ +// movl $0x80008840,%eax +// mov $0xcf8,%dx +// outl %eax,%dx +// mov $0xfc,%dl +// inl %dx,%eax + movb $0xbb, %al + outb %al,$0x80 + xorw %sp,%sp + xorw %dx,%dx +// movl $DOC_STACK, %esp # set %sp +// movl $SPL_RAM, %edx # start of RAM +// xorl %ecx, %ecx # clear %ecx + movw $0x800, %si # point %si to CDSN Data area + movw $0x1000,%di # point %di to CDSN Control area + movw $DOC_SPL_START_BLK, %bp # start page of LinuxBIOS + movb $0x0, %ds:0x03(%di) + movb $0x84,%ds:0x02(%di) + movb $0x84,%ds:0x02(%di) + call delay4nop + movb $0x85,%ds:0x02(%di) + movb $0x85,%ds:0x02(%di) + call delay4nop +read_next_page: + movw $0x1000, %di # point %di to CDSN Control area + movw $0x800, %si +flash_command: + movb $0x13, %ds:0x04(%di) # start command cycle + call delay4nop + movb $0x00, %ds:(%si) # issue flash command Read00 + + movb $0x00, %ds:0x1e(%di) + movb $0x11, %ds:0x04(%di) + + movw %bp, %bx # %bp is current page number + +flash_address: + shll $0x08, %ebx + movw $0x03, %cx # this one is DANGEROUS but I am + + movb $0x15, %ds:0x04(%di) # start address cycle + call delay4nop +0: + movb %bl, %ds:(%si) # write address to CDSNIO + shrw $0x08, %bx # shift next address byte + loop 0b + movb $0x00, %ds:0x1e(%di) + movb $0x31, %ds:0x04(%di) +// call doc_cycle_end + call delay4nop + + +wait_for_flash_ready: + /* delay by reding NOP register before polling the FLASH READY bit, + this is inlined to save a call/ret pair */ +doc_delay: + movb %ds:0x04(%di),%ah + movw $0x04, %cx # this one is DANGEROUS but I am + # sure the upper 3 bytes == 0x00 +0: + movb %ds:0x20(%di), %al # read DOC NOP retisger + loop 0b # four times + + testb $0x80,%ah # is flash ready ? + jz wait_for_flash_ready + + movb %ds:0x1d(%di), %al # init read pipeline + movw $0x1ff, %cx # 1 page = 512 bytes + movw $0x800, %si # point %si to CDSN Data area + movw %dx, %di # restore saved current destination + + rep movsb + movw $0x101f,%si + movsb +// call dely4nop + movw %di, %dx # save current destination + mov %bp,%di + sub $128,%di + shl $9,%di + movb %es:(%di),%al + out %al,$0x80 +// DELAY(loop200) +// DELAY(loop200) +// mov $0xffff,%cx +//aa: loop aa + inc %di + movb %es:(%di),%al + out %al,$0x80 + incw %bp # increse current page number + cmpw $128, %bp # moved 63 KB ?? + jl read_next_page # no, read next page + +sis630ipl_end: + # jmp to 8000:0000, where SPL + # (LinuxBIOS) starts in RAM +# ljmp $0x10,$0x8000 + movb $0xdd, %al + outb %al,$0x80 + jmp spl_vector + +delay4nop: + movb %ds:0x20(%di),%al + movb %ds:0x20(%di),%al + movb %ds:0x20(%di),%al + movb %ds:0x20(%di),%al + ret + +//doc_reset: + /* Input: AL = value write to DOC_CONTROL register + Clobberd: CX */ +// movb %al, 0x02(%edi) # write DoC Control retister +// movb %al, 0x02(%edi) # twice +// ret # End of doc_reset + +//doc_cycle_end: +// movb $0x00, 0x1e(%di) # flush write pepeline +// movb $0x31, 0x04(%di) # end command cycle +// ret + + +/* we don't need these. We only do I/O to MCR 0 */ +#if 0 +pci_write_dword: + mov $0,%ah + mov $0x80000000,%edx + or %ax,%dx + mov %edx,%eax + mov $0x0cf8,%dx + outl %eax,%dx + mov $0x0fc,%dl + mov %ecx, %eax + outl %eax,%dx + RETSP +pci_read_dword: + mov $0,%ah + mov $0x80000000,%edx + or %ax,%dx + mov %edx,%eax + mov $0x0cf8,%dx + outl %eax,%dx + mov $0x0fc,%dl + inl %dx, %eax + mov %eax, %ecx + RETSP +#endif + + .org 0x01f0 +reset_vector: + .byte 0xea #jump to fe00:0000, where IPL + .word 0x0000, DOC_WIN_SEG #starts in DoC + +spl_vector: +// invd +// movb $0xdd,%al +// outb %al,$0x80 +// jmpl $0x10, $0x80000 + .byte 0xea + .word 0x0000, 0x8000 +# jumpl $0x80000 +# put this here to buy some room +pad: .byte 0,0,0,0,0,0 diff --git a/src/northbridge/via/vt694/northbridge.c b/src/northbridge/via/vt694/northbridge.c new file mode 100644 index 0000000000..692de36ee8 --- /dev/null +++ b/src/northbridge/via/vt694/northbridge.c @@ -0,0 +1,74 @@ +#include +#include +#include + + +unsigned long sizeram() +{ + unsigned long totalmem; + unsigned char bank, mem, prevmem; + // fix me later -- there are two more banks at 0x56 and 0x57 + unsigned long firstbank = 0x5a, lastbank = 0x5f; + u8 sma_status, sma_size, sma_size_bits; + + struct pci_dev *pcidev; + + pcidev = pci_find_slot(0, PCI_DEVFN(0,0)); + + if (! pcidev) + return 0; + + pci_read_config_byte(pcidev, 0xfb, &sma_status); + sma_size_bits = (sma_status >> 4) & 0x03; + if (sma_size_bits > 3) + sma_size = 0; + else + sma_size = 0x01 << sma_size_bits; + + for(totalmem = mem = prevmem = 0, bank = firstbank; + bank <= lastbank; bank++) { + pci_read_config_byte(pcidev, bank, &mem); + // sanity check. If the mem value is < prevmem, + // that is an error, so skip this step. + if (mem < prevmem) { + printk_err("ERROR: bank 0x%x, mem 0x%x TOO SMALL\n", + bank, prevmem); + printk_err("Should be >= 0x%x\n", prevmem); + } else + totalmem += (mem - prevmem) * 8; + prevmem = mem; + } + + totalmem -= sma_size; + totalmem *= 1024; + + printk_info("sizeram: returning 0x%x KB\n", totalmem); + printk_info("sizeram: NOT returning 0x%x KB\n", totalmem); + printk_info("sizeram: there are still some SPD problems ... \n"); + totalmem = 64 * 1024; + printk_info("sizeram: SO we return only 0x%x KB\n", totalmem); +#if 0 +#endif + return totalmem; +} + + +/* +unsigned long sizeram() +{ + return 0; +} +*/ + +#ifdef HAVE_FRAMEBUFFER +void framebuffer_on() +{ + unsigned long devfn; + u16 command; + + devfn = PCI_DEVFN(0, 1); + pcibios_read_config_word(0, devfn, 0x3e, &command); + command |= 0x08; + pcibios_write_config_word(0, devfn, 0x3e, command); +} +#endif diff --git a/src/northbridge/via/vt694/raminit.inc b/src/northbridge/via/vt694/raminit.inc new file mode 100644 index 0000000000..4191578061 --- /dev/null +++ b/src/northbridge/via/vt694/raminit.inc @@ -0,0 +1,171 @@ +/* +This software and ancillary information (herein called SOFTWARE ) +called LinuxBIOS is made available under the terms described +here. The SOFTWARE has been approved for release with associated +LA-CC Number 00-34 . Unless otherwise indicated, this SOFTWARE has +been authored by an employee or employees of the University of +California, operator of the Los Alamos National Laboratory under +Contract No. W-7405-ENG-36 with the U.S. Department of Energy. The +U.S. Government has rights to use, reproduce, and distribute this +SOFTWARE. The public may copy, distribute, prepare derivative works +and publicly display this SOFTWARE without charge, provided that this +Notice and any statement of authorship are reproduced on all copies. +Neither the Government nor the University makes any warranty, express +or implied, or assumes any liability or responsibility for the use of +this SOFTWARE. If SOFTWARE is modified to produce derivative works, +such modified SOFTWARE should be clearly marked, so as not to confuse +it with the version available from LANL. + */ +/* Copyright 2000, Ron Minnich, Advanced Computing Lab, LANL + * rminnich@lanl.gov + */ + +#define loop200 $0x5000 +#define loop100 $0x2500 + +/*; new code... pulled from via stuff.*/ +/* initialize registers */ + // memory clk enable. We are not using ECC + CS_WRITE($0x78, $0x01) + // dram control, see the book. + CS_WRITE($0x68, $0x00) + // dram control, see the book. + CS_WRITE($0x6B, $0x00) + // 64/128 MB dram + CS_WRITE($0x58, $0x88) + // 64/128 MB dram + CS_WRITE($0x59, $0x88) + // bank 0 ends at 64 MB + CS_WRITE($0x5A, $0x08) + // bank 1 ends at 64 MB + CS_WRITE($0x5B, $0x10) + // bank 2 ends at 64 MB + CS_WRITE($0x5C, $0x10) + // bank 2 ends at 64 MB + CS_WRITE($0x5D, $0x10) + // bank 2 ends at 64 MB + CS_WRITE($0x5E, $0x10) + // bank 2 ends at 64 MB + CS_WRITE($0x5F, $0x10) + + // SDRAM in all banks + CS_WRITE($0x60, $0xFF) + // DRAM timing. I'm suspicious of this + // This is for all banks, 64 is 0,1. 65 is 2,3. 66 is 4,5. + // ras precharge 4T, RAS pulse 5T, CAS 2T + // as per the note below, we change to cas 3 2000/8/31 + // cas2 is 0xd6, cas3 is 0xe6 + // we're also backing off write pulse width to 2T, so result is 0xee + CS_WRITE($0x64, $0xee) + CS_WRITE($0x65, $0xee) + CS_WRITE($0x66, $0xee) + + // dram frequency select. We set 66/66. + // no 256 m, enable 4K pages for 64M dram. + CS_WRITE($0x69, $0x04) + // refresh counter, disabled. + CS_WRITE($0x6A, $0x00) + // clkenable configuration. Not sure this is right! + CS_WRITE($0x6C, $0x00) + // dram read latch delay of 1 ns, MD drive 8 mA, + // high drive strength on MA[2: 13], we#, cas#, ras# + // As per Cindy Lee, set to 0x37, not 0x57 + CS_WRITE($0x6D, $0x37) + +/* begin to initialize*/ + // I forget why we need this, but we do + mov $0xa55a5aa5, %eax + mov %eax, 0 + mov %eax, 0x4000000 + +/* set NOP*/ + CS_WRITE($0x6C, $0x01) + + +/* wait 200us*/ + // You need to do the memory reference. That causes the nop cycle. + mov 0x0, %eax + mov 0x4000000, %eax + DELAY(loop200) + + +/* set precharge */ + CS_WRITE($0x6C, $0x02) + +/* dummy reads*/ + mov 0x0, %eax + mov 0x4000000, %eax + +/* set CBR*/ + CS_WRITE($0x6C, $0x04) + +/* do 8 reads and wait 100us between each - from via*/ + mov 0x0, %eax + mov 0x4000000, %eax + DELAY(loop100) + mov 0x0, %eax + mov 0x4000000, %eax + DELAY(loop100) + mov 0x0, %eax + mov 0x4000000, %eax + DELAY(loop100) + mov 0x0, %eax + mov 0x4000000, %eax + DELAY(loop100) + mov 0x0, %eax + mov 0x4000000, %eax + DELAY(loop100) + mov 0x0, %eax + mov 0x4000000, %eax + DELAY(loop100) + mov 0x0, %eax + mov 0x4000000, %eax + DELAY(loop100) + mov 0x0, %eax + mov 0x4000000, %eax + DELAY(loop100) + +/* set MRS*/ + // 0x150 is cas2. We are now using 0x1d0, which is cas3 + CS_WRITE($0x6c, $0x03) + movl $0x1d0, %ecx + movl (%ecx), %eax + movl $0x40001d0, %ecx + movl (%ecx), %eax + +/* set to normal mode */ + CS_WRITE($0x6C, $0x00) + movl $0x55aa55aa, %eax + mov %eax, 0x0 + mov 0x0, %eax + + // Set the refresh rate. + CS_WRITE($0x6A, $0x65) + // enable multi-page open + CS_WRITE($0x6B, $0x01) + + +/* From Mike Fan: + Hi all: + If you are porting PM133, then you have to set DRAM Row Ending Address. + You did not set Rx56 and Rx57 in intel_pm133ram.S. + That register setting is like Rx5A~Rx5F. + Maybe could fix the mem wrapping issue. + (from Ron Minnich) + My manual says these are non-cacheable region registers. + (Turns out the manual is wrong. However, this did not help. + 2000/8/31 8:49 am I am setting all dram to cas3, and if that fails, + I'll be trying some of Cindy's other recommendations. + DRAM is currently CAS2. Symptom is an explosion in free_all_bootmem_core, + In the loop where it is freeing bootmem alloc pages from low mem. + 2000/8/31: 10:57 No change, Linux still crashes. We'll try Cindy Lee's recommendation + RE Register 0x6d, set it to 0x37. All our other settings conform to her + other recommendations. We also need to see whether we should be setting + Fixed MTRRs, but that seems unlikely. + 2000/8/31: 5:56 PM. No significant change. We're going to try to use 1 cycle writes + instead of 2. None of this feels like it is the real problem. Fixed MTRRs + helped a tiny bit. We can get to schedule() before we crash, but only + if we set a breakpoint after the first loop in free_all_bootmem_core + */ + CS_WRITE($0x56, $0x10) + CS_WRITE($0x57, $0x10) diff --git a/src/northbridge/via/vt694/raminitspd.inc b/src/northbridge/via/vt694/raminitspd.inc new file mode 100644 index 0000000000..3c7b6017ca --- /dev/null +++ b/src/northbridge/via/vt694/raminitspd.inc @@ -0,0 +1,382 @@ +/* + v1.0: 02/14/2001: Program procedure to make workable and stable register settings: + (1) Initial registers: 0x68:0x00, 0x6a:0x00, 0x6b:0x00, 0x6c:0x00, + 0x64:0xe4, 0x65:0xe4, 0x66:0xe4, 0x50:0xfe, + 0xf8:0x22, 0xf9:0x42, 0xfb:0xb0, 0x6d:0x01, + 0x60:0xff, 0x58:0x40, 0x59:0x00, 0x5a:0x20, + 0x5b:0x40, 0x5c:0x60, 0x5d:0x80, 0x5e:0xa0, + 0x5f:0xc0, 0x56:0xe0, 0x57:0xff + (2) When SPD routine: Changed 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f + (3) After SPD, the special register setting: + (i) First to write: 0x56--0x57:(0x5f), 0x6a:65 + (ii) Second to write: 0x6b:0x01, 0x78:0x01, 0x58:0x80, 0x6d:0x21 + v1.1: 02/14/2001: To add: + (1) Initial registers: 0x51:0xdf, 0x52:0xc8, 0x53:0x98, 0x64:0xe6, 0x65:0xe6, 0x66:0xe6 + (2) After SPD, the special register setting: + (i) First to write: or 0x68:0x01-->0x68:0x41, or 0x69:0x00-->0x69:0x2c + (i) Second to write: 0x6d:0x21-->0x6d:0x57i + TO TEST: To change 0x64:0xe4 to 0x64:0x12, 0x65:0xe4 to 0x65:0xe6, 0x66:0xe4 to 0x66:0xe6 + Result: fail!! It will cause too many errors message. + SDRAM verify: + 00000000:0005ff80 + 00000004:0005ff84 + 00000008:00000000 + 0000000c:00000004 + 00000010:00000008 + 00000014:0000000c + 00000018:00000010 + 0000001c:00000014 + 00000020:0005ff80 + 00000024:0005ffa4 + ................. + ................. + Too many errors. + v1.2: 02/14/2001: To modify: + (1) Initial register: 0x6b:0x00--> 0x6b:0x2d + (2) After SPD, the special register setting: + (i) Second to modify: or 0x6b:0x2d-->0x6b:0x2f, or 0x6c:0x00-->0x08 + v1.3: 02/04/2001: To add: + (1) Initial registers: 0x71:0x08, 0x75:0x80, 0x76:0x80, 0x79:0xf0, 0x7f:0x04 + v1.4: 02/04/2001: To modify: + (1) After SPD, set registers: + (1) Second to write and modify: 0x70:0xc0, or 0x71:08-->0x71:88, 0x72:ec, 0x73:0c, 0x74:0x0e, + or 0x75:0x80-->0x75:0x81, or 0x76:0x80-->0x76:0xd6, or 0x79:0xf0-->0x79:0xf4, 0x7a:0x01 + v1.5: 02/15/2001: To modify and add: + (1) Initial register: 0x81:0xc3 + To add ptp table(bus0, devfn08) and program: 0x1c:0xf0, 0x20:0xf0, 0x21:0xff, 0x24:0xf0, 0x25:0xff, 0x34:0x80 + (2) After SPD, set registers: + (1) Second to write: 0x0d:0x08, 0xac:0x6e + +*/ + +/* SPD ram init */ +#define PM_DEVFN CONFIG_ADDR(0, PM_DEVICE, 0) +#define DRAM_CONFIG_PORT 0x5a +#define REGISTERED_DRAM_REGISTER $0x69 +#define LAST_SMBUS_MEM_DEVICE SMBUS_MEM_DEVICE_2 + +jmp raminitspd_end +/* table of settings for initial registers */ +register_table: +/* no memory clock enable -- overridden by SPD, we hope */ +// .byte 0x78, 0x1 +/* safe initial values ... */ + .byte 0x68, 0x0 + .byte 0x6a, 0x0 /* disable refresh */ +// .byte 0x6b, 0x0 + .byte 0x6b, 0x2d + .byte 0x6c, 0x0 /* disable ECC for start */ +// .byte 0x6d, 0x37 /* as per Cindy Lee, ... */ +// .byte 0x64, 0xe4 /* slowest ram setting. banks 0, 1 */ +// .byte 0x65, 0xe4 /* banks 2, 3*/ +// .byte 0x66, 0xe4 /* banks 4, 5 */ + .byte 0x64, 0xe6 + .byte 0x65, 0xe6 + .byte 0x66, 0xe6 + + .byte 0x50, 0xfe + .byte 0x51, 0xdf + .byte 0x52, 0xc8 + .byte 0x53, 0x98 + .byte 0xf8, 0x22 + .byte 0xf9, 0x42 + .byte 0xfb, 0xb0 + +/* we tried increasing the drive, but that did not help or hurt. + * We will leave it at low drive for now, however. + */ +#if 1 +/* the standard BIOS goes for 0x5f here, which is very high drive. + * Try it out. RGM 1/26/1 */ +/* LOW DRIVE */ +// .byte 0x6d, 0x5 /* 0x4 = 24 ma on ma[2:13],we#, 24ma on ras# */ + .byte 0x6d, 0x1 +#else + /* HIGH DRIVE */ + .byte 0x6d, 0x5f /* 0x4 = 24 ma on ma[2:13],we#, 24ma on ras# */ +#endif + .byte 0x60, 0xff /* sdram in ALL banks. It's all we do. */ +/* set these to 0xee (128 MB VC SDRAM). In our working code we set to + * 0x88, but VIA code recommends 0xee. Since we are SPD, in the end, + * this initial setting will be over-ridden by SPD probe values. + * leave at 88 for now -- deal with this mess later + */ +// .byte 0x58, 0x88 +// .byte 0x59, 0x88 + .byte 0x58, 0x40 + .byte 0x59, 0x00 +/* size the banks at max, they will be resized later. */ + .byte 0x5a, 0x20 + .byte 0x5b, 0x40 + .byte 0x5c, 0x60 + .byte 0x5d, 0x80 + .byte 0x5e, 0xa0 + .byte 0x5f, 0xc0 + .byte 0x56, 0xe0 + .byte 0x57, 0xff + + .byte 0x71, 0x08 + .byte 0x75, 0x80 + .byte 0x76, 0x80 + .byte 0x79, 0xf0 + + .byte 0x81, 0xc3 + .byte 0x0 /* end of table */ + +ptp_table: + .byte 0x1c, 0xf0 + .byte 0x20, 0xf0 + .byte 0x21, 0xff + .byte 0x24, 0xf0 + .byte 0x25, 0xff + .byte 0x34, 0x80 + .byte 0x0 + +ram_set_registers: + /* standard x86 loop on table until done code */ + /* assumes that: devfn is 0 (safe on anything we've seen) */ + /* which means addresses are a byte */ + /* address is first, then data */ + movl $register_table, %esi +1: + /* zero out eax. This is a must right here. */ + xor %eax, %eax + movb (%esi), %al + testb %al, %al +// jz done_ram_set_registers + jz ptp + inc %esi + movb (%esi), %dl + PCI_WRITE_CONFIG_BYTE + inc %esi + jmp 1b + +ptp: movl $ptp_table, %esi +2: + /* zero out eax. This is a must right here. */ + xor %eax, %eax + movb (%esi), %al + testb %al, %al + jz done_ram_set_registers + inc %esi + orl $0x0800, %eax + movb (%esi), %dl + PCI_WRITE_CONFIG_BYTE + inc %esi + jmp 2b + // I forget why we need this, but we do + + mov $0xa55a5aa5, %eax + mov %eax, 0 + mov %eax, 0x4000000 + intel_chip_post_macro(0x01) + +done_ram_set_registers: RET_LABEL(ram_set_registers) +ram_set_spd_registers: + CALL_LABEL(enable_smbus) + intel_chip_post_macro(0x02) + + CALL_LABEL(setup_smbus) + intel_chip_post_macro(0x03) + + CALL_LABEL(spd_set_drb) + intel_chip_post_macro(0x04) + + CALL_LABEL(spd_set_dramc) + intel_chip_post_macro(0x05) + +/* CALL_LABEL(spd_set_rps)*/ +/* CALL_LABEL(spd_set_sdramc)*/ +/* CALL_LABEL(spd_set_pgpol)*/ +/* CALL_LABEL(spd_set_nbxcfg)*/ +spd_set_rps_done: +spd_set_pgpol_done: +spd_set_nbxcfg_done: + + RET_LABEL(ram_set_spd_registers) + +#define SMBUS_IO_BASE 0xf00 +#define REGISTERED_DRAM $0x2 +#define NONREGISTERED_DRAM $0 +#define REGISTER_DRAM_REGISTER $0x69 + +#define RAM_READ 0x0400 + +#define DIMM0_BASE \ + intel_chip_post_macro(0x06) ; \ + xorl %eax, %eax + +#define DIMM_BASE(n) \ + intel_chip_post_macro(0x07) ; \ + movl $(0x5a + ((n) -1)), %eax ; \ + PCI_READ_CONFIG_BYTE ; \ + andl $0xFF, %eax ; \ + shll $23, %eax ; \ + +#define DIMM_READ \ + addl %ebx, %eax ; \ + movl (%eax), %edx /* end it here -- see if that fixes */ +#if 0 + xorl $0xdff8, %eax ; \ + movl (%eax), %edx +#endif + +#define DIMM0_READ DIMM0_BASE ; DIMM_READ +#define DIMM1_READ DIMM_BASE(1) ; DIMM_READ +#define DIMM2_READ DIMM_BASE(2) ; DIMM_READ +#define DIMM3_READ DIMM_BASE(3) ; DIMM_READ +#define DIMM4_READ DIMM_BASE(4) ; DIMM_READ +#define DIMM5_READ DIMM_BASE(5) ; DIMM_READ +#define DIMM6_READ DIMM_BASE(6) ; DIMM_READ +#define DIMM7_READ DIMM_BASE(7) ; DIMM_READ + +#define DIMMS_READ_EBX_OFFSET \ + intel_chip_post_macro(0x08) ; \ + DIMM0_READ ; \ + intel_chip_post_macro(0x09) ; \ + DIMM1_READ ; \ + intel_chip_post_macro(0x0a) ; \ + DIMM2_READ ; \ + intel_chip_post_macro(0x0b) ; \ + DIMM3_READ ; \ + intel_chip_post_macro(0x0c) ; \ + DIMM4_READ ; \ + intel_chip_post_macro(0x0d) ; \ + DIMM5_READ ; \ + intel_chip_post_macro(0x0e) ; \ + DIMM6_READ ; \ + intel_chip_post_macro(0x0f) ; \ + DIMM7_READ + +#define DIMMS_READ(offset) \ + movl $offset, %ebx ; \ + DIMMS_READ_EBX_OFFSET + +#define RAM_COMMAND_NONE 0x0 +#define RAM_COMMAND_NOP 0x1 +#define RAM_COMMAND_PRECHARGE 0x2 +#define RAM_COMMAND_MRS 0x3 +#define RAM_COMMAND_CBR 0x4 + +#define SET_RAM_COMMAND(command) \ + intel_chip_post_macro(0x20) ; \ + movl $0x6c, %eax ; \ + PCI_READ_CONFIG_BYTE ; \ + andl $0x18, %eax ; \ + orl $(command), %eax ; \ + movl %eax, %edx ; \ + movl $0x6c, %eax ; \ + PCI_WRITE_CONFIG_BYTE + +// fix me later. Have to have ram in slot 0, and we only test cas3 or 2 +#define COMPUTE_CAS_MODE \ + intel_chip_post_macro(0x21) ; \ + movl $0x64, %eax ; \ + PCI_READ_CONFIG_BYTE ; \ + andl $0x20, %eax ; \ + xorl $0x20, %eax ; \ + shrl $1, %eax ; \ + orl $0x2a, %eax ; \ + +#define SET_RAM_MODE_REGISTER \ + SET_RAM_COMMAND(RAM_COMMAND_MRS) ; \ + COMPUTE_CAS_MODE ; \ + shll $3, %eax ; \ + /* FIX ME -- set to cas3 no matter what for now */ ; \ + movl $0x1d0, %eax; \ + movl %eax, %ebx ; \ + DIMMS_READ_EBX_OFFSET + +#define ASSERT_RAM_COMMAND() DIMMS_READ(RAM_READ) +#define ASSERT_MRS_RAM_COMMAND(mode) DIMMS_READ(mode) +#define USE_SPD 1 +#if ! USE_SPD +#define ENABLE_REFRESH() CS_BIS_BYTE(0x57, 0x1) +#else /* USE_SPD */ +#define ENABLE_REFRESH() CALL_LABEL(spd_enable_refresh) +#endif + +#define FIRST_NORMAL_REFERENCE() \ + intel_chip_post_macro(0x22) ; \ + movl $0x55aa55aa, %eax; \ + mov %eax, 0x0; \ + mov 0x0, %eax; + +// should also read 0x5f and write that to 0x56 and 0x57 + + +#define SPECIAL_FINISHUP() \ + intel_chip_post_macro(0x23) ; \ + /* enable multi-page open */; \ + CS_READ($0x6B) ; \ + movb %al, %dl ; \ + orb $0x02, %dl ; \ + movl $0x6b, %eax ; \ + PCI_WRITE_CONFIG_BYTE ; \ + CS_READ($0x6c) ; \ + movb %al, %dl ; \ + orb $0x08, %dl ; \ + movl $0x6c, %eax ; \ + PCI_WRITE_CONFIG_BYTE ; \ + CS_WRITE($0x78, $0x01) ; \ + movb $0x80, %dl; \ + movl $0x58, %eax; \ + PCI_WRITE_CONFIG_BYTE; \ + CS_WRITE($0x6d, $0x57) ; \ + CS_WRITE($0x70, $0xc0) ; \ + CS_READ($0x71) ; \ + movb %al, %dl ; \ + orb $0x80, %dl ; \ + movl $0x71, %eax ; \ + PCI_WRITE_CONFIG_BYTE ; \ + CS_WRITE($0x72, $0xec) ; \ + CS_WRITE($0x73, $0x0c) ; \ + CS_WRITE($0x74, $0x0e) ; \ + CS_READ($0x75) ; \ + movb %al, %dl ; \ + orb $0x01, %dl ; \ + movl $0x75, %eax ; \ + PCI_WRITE_CONFIG_BYTE ; \ + CS_READ($0x76) ; \ + movb %al, %dl ; \ + orb $0x52, %dl ; \ + movl $0x76, %eax ; \ + PCI_WRITE_CONFIG_BYTE ; \ + CS_READ($0x79) ; \ + movb %al, %dl ; \ + orb $0x04, %dl ; \ + movl $0x79, %eax ; \ + PCI_WRITE_CONFIG_BYTE ; \ + CS_WRITE($0x7a, $0x01) ; \ + CS_WRITE($0x0d, $0x08) ; \ + CS_WRITE($0xac, $0x6e) + +// CS_WRITE($0x6d, $0x21) ; \ +// CS_WRITE($0x84, $0xc0) + +spd_enable_refresh: + intel_chip_post_macro(0x24) ; \ + // just set it for now. + CS_WRITE($0x6A, $0x65) + + CS_READ($0x5f) + movb %al, %dl + movl $0x56, %eax + PCI_WRITE_CONFIG_BYTE + CS_READ($0x5f) + movb %al, %dl + movl $0x57, %eax + PCI_WRITE_CONFIG_BYTE + + CS_READ($0x68) + movb %al, %dl + orb $0x40, %dl + movl $0x68, %eax + PCI_WRITE_CONFIG_BYTE + CS_READ($0x69) + movb %al, %dl + orb $0x2c, %dl + movl $0x69, %eax + PCI_WRITE_CONFIG_BYTE + RET_LABEL(spd_enable_refresh) +raminitspd_end: