add sis 540 support
This commit is contained in:
parent
0fa43619fe
commit
42e38b5a3e
12 changed files with 987 additions and 0 deletions
10
src/mainboard/sis/540/Config
Normal file
10
src/mainboard/sis/540/Config
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
northsouthbridge sis/540
|
||||
# superio sis/950
|
||||
nsuperio sis/950 com1={1} floppy=1 lpt=1
|
||||
|
||||
option FINAL_MAINBOARD_FIXUP
|
||||
option HAVE_PIRQ_TABLE
|
||||
object mainboard.o
|
||||
object irq_tables.o
|
||||
keyboard pc80
|
||||
cpu p5
|
||||
8
src/mainboard/sis/540/dll.inc
Normal file
8
src/mainboard/sis/540/dll.inc
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
/* Table for DLL Clock Control Register (0x8c - 0x8f), these
|
||||
register values are very Mainboard specific */
|
||||
|
||||
# High Byte -> Register Low Byte -> Value
|
||||
.word 0x8c44 # set Clock DLL control register
|
||||
.word 0x8d86 # 0x8c ~ 0x8f,
|
||||
.word 0x8ec1 # these values are very M/B
|
||||
.word 0x8f46 # specific
|
||||
29
src/mainboard/sis/540/irq_tables.c
Normal file
29
src/mainboard/sis/540/irq_tables.c
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
#include <i386_subr.h>
|
||||
|
||||
#define CHECKSUM 0xe6
|
||||
const struct irq_routing_table intel_irq_routing_table = {
|
||||
PIRQ_SIGNATURE, /* u32 signature */
|
||||
PIRQ_VERSION, /* u16 version */
|
||||
32+16*5, /* there can be total 5 devices on the bus */
|
||||
0x00, /* Bus 0 */
|
||||
0x08, /* Device 1, Function 0 */
|
||||
0x0A20, /* reserve IRQ 11, 9, 5, for PCI */
|
||||
0x1039, /* Silicon Integrated System */
|
||||
0x0008, /* SiS 85C503/5513 ISA Bridge */
|
||||
0x00, /* u8 miniport_data - "crap" */
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* u8 rfu[11] */
|
||||
CHECKSUM, /* u8 checksum - mod 256 checksum must give zero */
|
||||
{
|
||||
/* bus, devfn, {link, bitmap}, {link, bitmap}, {link, bitmap}, {link, bitmap}, slot, rfu */
|
||||
{0x00, 0x58, {{0x43, 0xdef8}, {0x44, 0xdef8}, {0x41, 0xdef8}, {0x42, 0xdef8}},
|
||||
0x01, 0x00},
|
||||
{0x00, 0x60, {{0x44, 0xdef8}, {0x41, 0xdef8}, {0x42, 0xdef8}, {0x43, 0xdef8}},
|
||||
0x02, 0x00},
|
||||
{0x00, 0x01, {{0x61, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}},
|
||||
0x00, 0x00},
|
||||
{0x00, 0x10, {{0x41, 0xdef8}, {0x42, 0xdef8}, {0x43, 0xdef8}, {0x44, 0xdef8}},
|
||||
0x00, 0x00},
|
||||
{0x00, 0x0a, {{0x41, 0xdef8}, {0x42, 0xdef8}, {0x43, 0xdef8}, {0x44, 0xdef8}},
|
||||
0x00, 0x00},
|
||||
}
|
||||
};
|
||||
21
src/mainboard/sis/540/mainboard.c
Normal file
21
src/mainboard/sis/540/mainboard.c
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
#include <printk.h>
|
||||
|
||||
void
|
||||
mainboard_fixup(void)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
final_mainboard_fixup(void)
|
||||
{
|
||||
void final_southbridge_fixup(void);
|
||||
void final_superio_fixup(void);
|
||||
|
||||
printk(KERN_INFO
|
||||
"SiS 540 (and similar)...");
|
||||
|
||||
final_southbridge_fixup();
|
||||
#ifndef USE_NEW_SUPERIO_INTERFACE
|
||||
final_superio_fixup();
|
||||
#endif
|
||||
}
|
||||
106
src/northsouthbridge/sis/540/540_regs.inc
Normal file
106
src/northsouthbridge/sis/540/540_regs.inc
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
/*
|
||||
* 630_regs.inc: Register Recommended Setting for SiS 630 [ABE][01]
|
||||
*
|
||||
*
|
||||
* 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. SiS 630A1 Register Recommended Setting
|
||||
* Rev 0.97, Jan 7, 2000
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
northbridge_init_table:
|
||||
# Reg. Value
|
||||
/* generic PCI configuration space */
|
||||
.byte 0x04, 0x07 # Turn on Bus Master,
|
||||
.byte 0x05, 0x00 # Memory and I/O Space
|
||||
.byte 0x06, 0x00 # clear PCI status
|
||||
.byte 0x07, 0x00 #
|
||||
.byte 0x0D, 0x20 # Master Latency Timer = 32 PCI CLCK
|
||||
|
||||
.byte 0x13, 0xe0
|
||||
|
||||
/* SiS 540 specific registers. See SiS 540 Registers Recommended Setting */
|
||||
|
||||
/* Host Control Interface */
|
||||
.byte 0x50, 0xfe #
|
||||
.byte 0x51, 0x08 #
|
||||
|
||||
/* DRAM Control */
|
||||
.byte 0x52, 0xC5 #
|
||||
.byte 0x53, 0xc0 #
|
||||
|
||||
.byte 0x54, 0x08 #
|
||||
.byte 0x55, 0x01 #
|
||||
.byte 0x56, 0x00 #
|
||||
.byte 0x57, 0x00 #
|
||||
|
||||
/* Pre-driver Slew Rate/Current Driving Control */
|
||||
.byte 0x58, 0x00 #
|
||||
.byte 0x59, 0x55 #
|
||||
.byte 0x5A, 0x55 #
|
||||
.byte 0x5B, 0x00 #
|
||||
|
||||
.byte 0x65, 0x00 # Use DIMM 0 for SMA
|
||||
|
||||
/* MISC Control */
|
||||
// .byte 0x6A, 0xC0 #
|
||||
// .byte 0x6B, 0x01 # 0x00 -> 66/133 MHZ, 0x01 -> 100 MHZ
|
||||
// .byte 0x6C, 0x20 # 0x2E -> 66 MHZ, 0x20 -> 100 MHZ, 0x2C -> 133 MHZ
|
||||
|
||||
/* PCI Interface */
|
||||
.byte 0x80, 0x01 #
|
||||
.byte 0x81, 0xd1 #
|
||||
.byte 0x82, 0xce #
|
||||
.byte 0x83, 0x1b #
|
||||
|
||||
.byte 0x84, 0x60 #
|
||||
.byte 0x85, 0x00 #
|
||||
.byte 0x86, 0x03 #
|
||||
// .byte 0x87, 0x00 #
|
||||
.byte 0x88, 0x00 #
|
||||
.byte 0x89, 0x08 #
|
||||
|
||||
.byte 0x8a, 0x00 #
|
||||
.byte 0x8b, 0x00 #
|
||||
|
||||
/* AGP GART Base Address */
|
||||
.byte 0x90, 0x00
|
||||
.byte 0x91, 0x00
|
||||
.byte 0x92, 0x00
|
||||
.byte 0x93, 0x00
|
||||
|
||||
/* Graphic Window Size */
|
||||
.byte 0x94, 0x40 # Graphic Window Size == 64MB
|
||||
.byte 0x97, 0x01 # Page Table Cache Enable
|
||||
.byte 0x98, 0x00 #
|
||||
|
||||
/* DRAM Priority Timer Control Register */
|
||||
.byte 0xA0, 0x00
|
||||
.byte 0xA1, 0x00
|
||||
.byte 0xA2, 0x03
|
||||
.byte 0xA3, 0x01
|
||||
|
||||
/* AGP Command Register */
|
||||
// .byte 0xC8, 0x04 # AGP 4X
|
||||
// .byte 0xC9, 0x00 # AGP Disabled
|
||||
|
||||
northbridge_init_table_end:
|
||||
7
src/northsouthbridge/sis/540/Config
Normal file
7
src/northsouthbridge/sis/540/Config
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
option SIS540
|
||||
option USE_DOC_MIL
|
||||
docipl northsouthbridge/sis/540/ipl.S
|
||||
raminit northsouthbridge/sis/540/raminit.inc
|
||||
|
||||
object southbridge.o
|
||||
object northbridge.o
|
||||
408
src/northsouthbridge/sis/540/ipl.S
Normal file
408
src/northsouthbridge/sis/540/ipl.S
Normal file
|
|
@ -0,0 +1,408 @@
|
|||
/*
|
||||
* 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$
|
||||
*/
|
||||
|
||||
#include "ipl.h"
|
||||
|
||||
.code16
|
||||
|
||||
#define SIZE_ALL
|
||||
#define REALLY_COMPACT
|
||||
|
||||
sis630spd_start:
|
||||
cli # Disables the maskable
|
||||
# hardware interrupts.
|
||||
|
||||
movw %cs, %ax # makes data segment ==
|
||||
movw %ax, %ds # code segment
|
||||
|
||||
movw $0x408a, %ax # ACPI Enable.
|
||||
CALL_SP(write_lpc_register) # (for use of SMBus)
|
||||
|
||||
movw $0x7550, %ax # Store ACPI Base Address.
|
||||
CALL_SP(write_lpc_register) # (for use of SMBus)
|
||||
|
||||
movw $0x5501, %ax # Mode# enable, this bit
|
||||
CALL_SP(write_pci_register) # should be set before sizing.
|
||||
|
||||
#ifdef SIZE_ALL
|
||||
xorw %bx, %bx # clear %fs, %fs is used as "bitmap" of
|
||||
movw %bx, %fs # install DIMM slot
|
||||
#endif /* SIZE_ALL */
|
||||
|
||||
spd_sizing_start:
|
||||
#ifndef REALLY_COMPACT
|
||||
movw $0x0320, %ax # Issue an SMB_Kill command to
|
||||
CALL_BP(sis_set_smbus) # stop all SMBus operation
|
||||
#endif /* REALLY_COMPACT */
|
||||
|
||||
movw $0x04a1, %ax # SPD is on SMBUS Address 1010 xyz1
|
||||
# where xyz are DIMM Slot Number
|
||||
#ifdef SIZE_ALL
|
||||
addb %bh, %al # FIXME, %bh == 0 ??
|
||||
addb %bh, %al # Select the DIMM to be SPD-sized.
|
||||
#endif /* SIZE_ALL*/
|
||||
|
||||
CALL_BP(sis_set_smbus)
|
||||
|
||||
movb $0x02, %al # Read the RAM Type (SPD byte 2)
|
||||
CALL_SP(read_spd) # of the dram on current DIMM.
|
||||
|
||||
cmpb $0x04, %bl # If the RAM Type = SDRAM ??
|
||||
jne no_sdram # no, exit
|
||||
|
||||
movb $0x03, %al # Read the Row number (SPD byte 3)
|
||||
CALL_SP(read_spd) # of the dram on current DIMM.
|
||||
movb %bl, %ch # save the Row number in CH.
|
||||
|
||||
movb $0x04, %al # Read the Column number (SPD byte 4)
|
||||
CALL_SP(read_spd) # of the dram on current DIMM.
|
||||
movb %bl, %cl # Save the Column number in CL.
|
||||
|
||||
movb $0x11, %al # Read the Bank number (SPD byte 17)
|
||||
CALL_SP(read_spd) # of the dram on current DIMM.
|
||||
|
||||
#ifdef SIZE_ALL
|
||||
movb %bh, %ah # Save the current DIMM slot number in AH
|
||||
#endif
|
||||
|
||||
cmpb $0x01, %bl
|
||||
je one_bank
|
||||
|
||||
movw $sdram_type_bank_2, %si
|
||||
jmp check_row_column
|
||||
one_bank:
|
||||
movw $sdram_type_bank_1, %si
|
||||
|
||||
check_row_column:
|
||||
#ifdef SAFTY_CHECK
|
||||
cmpb $0x0b, %ch # Row number too small, unsupported.
|
||||
jb no_sdram
|
||||
cmpb $0x0d, %ch # Row number too big, unsupported.
|
||||
jl no_sdram
|
||||
cmpb $0x08, %cl # Col number too small, unsupported.
|
||||
jb no_sdram
|
||||
cmpb $0x0b, %cl # Col number too big, unsupported.
|
||||
jl no_sdram
|
||||
#endif /* SAFTY_CHECK */
|
||||
|
||||
#if 1
|
||||
subb $0x0b, %ch # row = row - 11
|
||||
shlb $0x02, %ch # row * 4
|
||||
|
||||
addb %ch, %cl # column + row * 4
|
||||
movzbw %cl, %bx # Get the SDRAM type.
|
||||
|
||||
addw %bx, %si # sdram_type_bank[column + row * 4]
|
||||
movb -8(%si), %cl # sdram_type_bank[column + row * 4 - 8]
|
||||
#else
|
||||
/* This one is DANGEROUS TOO, be careful about OVERFLOW !!! */
|
||||
shlb $0x02, %ch # row * 4
|
||||
|
||||
addb %ch, %cl # column + row *4
|
||||
xorb %ch, %ch
|
||||
|
||||
addw %cx, %si # sdram_type_bank[column + row * 4]
|
||||
movb -52(%si), %cl # sdram_type_bank[column + row * 4 - 52]
|
||||
#endif
|
||||
|
||||
#ifdef SIZE_ALL
|
||||
movb %ah, %bh # Restore DIMM slot number from AH to BH
|
||||
#endif /* SIZE_ALL */
|
||||
|
||||
#ifdef SAFTY_CHECK
|
||||
cmpb $0xff, %cl # SDRAM type supported ??
|
||||
je no_sdram # no, exit
|
||||
#endif /* SAFTY_CHECK */
|
||||
|
||||
movb $0x05, %al # Read the Side number (SPD byte 5)
|
||||
CALL_SP(read_spd) # of the dram on current DIMM.
|
||||
|
||||
cmpb $0x02, %bl # single or double sided ??
|
||||
jne single_side
|
||||
orb $0x20, %cl # set double side bit
|
||||
# (reg 0x60~0x62 bit 5)
|
||||
|
||||
single_side:
|
||||
movb %cl, %al # store DRAM type in al
|
||||
movb $0x60, %ah # select register 0x60
|
||||
|
||||
#ifdef SIZE_ALL
|
||||
addb %bh, %ah # select register 0x61, 0x62, accroding
|
||||
# to DIMM slot number (in BH)
|
||||
#endif /* SIZE_ALL */
|
||||
CALL_SP(write_pci_register) # write register 0x60~0x62 for each
|
||||
# DIMM slot
|
||||
|
||||
#ifdef SIZE_ALL
|
||||
movw %fs, %ax # enable DIMMx on reg. 63h and save
|
||||
# it in FS
|
||||
movb $0x01, %bl
|
||||
movb %bh, %cl
|
||||
shlb %cl, %bl
|
||||
orb %bl, %al
|
||||
movw %ax, %fs
|
||||
no_sdram:
|
||||
incb %bh
|
||||
cmpb $0x03, %bh # total 3 DIMM slots supported
|
||||
jb spd_sizing_start
|
||||
|
||||
movw %fs, %ax
|
||||
movb $0x63, %ah
|
||||
#ifdef HAVE_FRAMEBUFFER
|
||||
orb $0x90, %al # enable SMA 4 MB for VGA
|
||||
#endif /* HAVE_FRAMEBUFFER */
|
||||
|
||||
#else /* !SIZE_ALL */
|
||||
|
||||
no_sdram:
|
||||
#ifdef HAVE_FRAMEBUFFER
|
||||
# enable DIMM 0 and
|
||||
movw $0x6391, %ax # enable SMA 4 MB for VGA
|
||||
#else /* HAVE_FRAMEBUFFER */
|
||||
movw $0x6301, %ax # enable DIMM 0
|
||||
#endif /* HAVE_FRAMEBUFFER */
|
||||
|
||||
#endif /* SIZE_ALL */
|
||||
|
||||
CALL_SP(write_pci_register) # write register 0x63
|
||||
|
||||
movw $pci_init_table, %si
|
||||
init_sdram:
|
||||
lodsw (%si), %ax
|
||||
testw %ax, %ax
|
||||
jz init_complete
|
||||
|
||||
CALL_SP(write_pci_register)
|
||||
jmp init_sdram
|
||||
|
||||
init_complete:
|
||||
sis630ipl_start:
|
||||
/* 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
|
||||
|
||||
movw $sis950_init_table, %si # unlock SiS 950 LPC
|
||||
movw $0x05, %cx # select Clock Selection
|
||||
movw $0x2e, %dx # and Flash ROM I/F
|
||||
rep
|
||||
outsb
|
||||
movb $0xfd, %al # enable write, CLKIN = 24 MHZ
|
||||
outb %al, $0x2f
|
||||
|
||||
xorw %sp, %sp # clear %sp
|
||||
xorw %dx, %dx # clear %dx, start of RAM
|
||||
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 $0x84, %al # Reset DOC Millennium
|
||||
call doc_reset
|
||||
|
||||
movb $0x85, %al # Turn into Normal Mode
|
||||
call doc_reset
|
||||
|
||||
read_next_page:
|
||||
movw $0x1000, %di # point %di to CDSN Control area
|
||||
|
||||
flash_command:
|
||||
movb $0x03, 0x04(%di) # start command cycle
|
||||
movb $0x00, (%si) # issue flash command Read00
|
||||
call doc_cycle_end
|
||||
|
||||
movw %bp, %bx # %bp is current page number
|
||||
|
||||
flash_address:
|
||||
shll $0x08, %ebx
|
||||
movb $0x03, %cl # this one is DANGEROUS but I am
|
||||
# sure the upper 3 bytes == 0x00
|
||||
|
||||
movb $0x05, 0x04(%di) # start address cycle
|
||||
0:
|
||||
movb %bl, (%si) # write address to CDSNIO
|
||||
shrw $0x08, %bx # shift next address byte
|
||||
loop 0b
|
||||
|
||||
call doc_cycle_end
|
||||
|
||||
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 $0x04, %cl # this one is DANGEROUS but I am
|
||||
# sure the upper 3 bytes == 0x00
|
||||
0:
|
||||
movb 0x20(%di), %al # read DOC NOP retisger
|
||||
loop 0b # four times
|
||||
|
||||
testb $0x80, 0x04(%di) # is flash ready ?
|
||||
jz wait_for_flash_ready
|
||||
|
||||
movb 0x1d(%di), %al # init read pipeline
|
||||
movw $0x100, %cx # 1 page = 512 bytes
|
||||
movw $0x800, %si # point %si to CDSN Data area
|
||||
movw %dx, %di # restore saved current destination
|
||||
rep
|
||||
movsw
|
||||
|
||||
movw %di, %dx # save current destination
|
||||
incw %bp # increse current page number
|
||||
cmpw $128, %bp # moved 63 KB ??
|
||||
jl read_next_page # no, read next page
|
||||
|
||||
sis630ipl_end:
|
||||
jmp spl_vector # jump to SPL vector
|
||||
|
||||
/* ------------------------------------------------------------------------------------------*/
|
||||
|
||||
write_lpc_register:
|
||||
/* Input: AH - register number. AL - register value. */
|
||||
movl $LPC_BRIDGE_BASE_ADDR, %edx
|
||||
jmp write_common
|
||||
|
||||
write_pci_register:
|
||||
/* Input: AH - register number. AL - register value. */
|
||||
movl $NORTH_BRIDGE_BASE_ADDR, %edx
|
||||
|
||||
write_common:
|
||||
movw %ax, %cx # Save %ax to %cx.
|
||||
|
||||
movzbl %ch, %eax # add register address to
|
||||
addl %edx, %eax # PCI base address
|
||||
|
||||
movw $PCI_COMMAND_PORT, %dx
|
||||
outl %eax, %dx
|
||||
|
||||
movw $PCI_DATA_PORT, %dx
|
||||
andb $0x03, %al
|
||||
addb %al, %dl
|
||||
movb %cl, %al
|
||||
outb %al, %dx
|
||||
RET_SP # End of write_[lpc|pci]_reg
|
||||
|
||||
read_spd:
|
||||
/* Input: AH = 05h, AL = byte number of SPD to be read.
|
||||
Output: BL = The value of specified SPD byte. */
|
||||
movb $0x05, %ah
|
||||
CALL_BP(sis_set_smbus)
|
||||
|
||||
movw $0x0312, %ax # Start, R/W byte Data
|
||||
CALL_BP(sis_set_smbus)
|
||||
|
||||
wait_for_smbus_read:
|
||||
movb $0x80, %dl # Read SMBus status
|
||||
inb %dx, %al
|
||||
|
||||
testb $0x02, %al # if device errors
|
||||
jnz read_spd_fail # then skip read SPD
|
||||
|
||||
testb $0x08, %al # if not complete
|
||||
jz wait_for_smbus_read # then wait SPD data complete
|
||||
|
||||
read_spd_fail:
|
||||
movb $0x08, %ah
|
||||
|
||||
sis_get_smbus:
|
||||
/* Input: AH - register index.
|
||||
Output: AL - register value. */
|
||||
addb %ah, %dl # read SMBus byte 0
|
||||
inb %dx, %al
|
||||
movb %al, %bl # return result in BL
|
||||
|
||||
movw $0x00ff, %ax
|
||||
CALL_BP(sis_set_smbus) # clear ACPI 80h status
|
||||
|
||||
RET_SP # End of read_spd
|
||||
|
||||
sis_set_smbus:
|
||||
/* Input: AH - register index. AL - register value. */
|
||||
movw $SMB_BASE_ADDR, %dx
|
||||
addb %ah, %dl
|
||||
outb %al, %dx
|
||||
RET_BP # End of sis_set_smbus
|
||||
|
||||
doc_reset:
|
||||
/* Input: AL = value write to DOC_CONTROL register
|
||||
Clobberd: CX */
|
||||
movb %al, 0x02(%di) # write DoC Control retister
|
||||
movb %al, 0x02(%di) # twice
|
||||
ret # End of doc_reset
|
||||
|
||||
doc_cycle_end:
|
||||
movb $0x00, 0x1e(%di) # flush write pepeline
|
||||
movb $0x01, 0x04(%di) # end command cycle
|
||||
ret
|
||||
|
||||
sdram_type_bank_1:
|
||||
# Column Number 8 9 10 11 Row Number
|
||||
.byte 0b0000, 0b0100, 0b1000, 0xff # 11
|
||||
.byte 0xff, 0xff, 0xff, 0xff # 12
|
||||
.byte 0b0001, 0b0101, 0b1001, 0b1101 # 13
|
||||
|
||||
sdram_type_bank_2:
|
||||
# Column Number 8 9 10 11 Row Number
|
||||
.byte 0b1100, 0xff, 0xff, 0xff # 11
|
||||
.byte 0b0010, 0b0110, 0b1010, 0b1110 # 12
|
||||
.byte 0b0011, 0b0111, 0b1011, 0b1111 # 13
|
||||
|
||||
pci_init_table:
|
||||
# High Byte -> Register Low Byte -> Value
|
||||
|
||||
//#include "dll.inc"
|
||||
|
||||
.word 0x8c44 # Precharge
|
||||
.word 0x8d86 # Mode Register Set
|
||||
.word 0x8ec1 # Refresh
|
||||
.word 0x8f46 # Refresh
|
||||
|
||||
.word 0x5780 # Precharge
|
||||
.word 0x5740 # Mode Register Set
|
||||
.word 0x5720 # Refresh
|
||||
.word 0x5720 # Refresh
|
||||
.word 0x5720 # Refresh
|
||||
.word 0x5201 # Refresh Cycle Enable
|
||||
.word 0x0000 /* Null, End of table */
|
||||
|
||||
.org 0x01f0
|
||||
reset_vector:
|
||||
.byte 0xea # jmp to fe00:0000, where IPL
|
||||
.word 0x0000, DOC_WIN_SEG # starts in DoC
|
||||
|
||||
spl_vector:
|
||||
.byte 0xea # jmp to 8000:0000, where SPL
|
||||
.word 0x0000, SPL_RAM_SEG # (LinuxBIOS) starts in RAM
|
||||
|
||||
sis950_init_table:
|
||||
.byte 0x87, 0x01, 0x55, 0x55, 0x24
|
||||
|
||||
end:
|
||||
hlt
|
||||
37
src/northsouthbridge/sis/540/ipl.h
Normal file
37
src/northsouthbridge/sis/540/ipl.h
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
#define PCI_COMMAND_PORT 0xcf8
|
||||
#define PCI_DATA_PORT 0xcfc
|
||||
|
||||
#define NORTH_BRIDGE_BASE_ADDR 0x80000000
|
||||
#define LPC_BRIDGE_BASE_ADDR 0x80000800
|
||||
|
||||
#define SMB_BASE_ADDR 0x5080
|
||||
|
||||
#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 126 /* 1 page = 512 bytes, total 63kB */
|
||||
|
||||
#define RET_LABEL(label) \
|
||||
jmp label##_done
|
||||
|
||||
#define CALL_LABEL(label) \
|
||||
jmp label ;\
|
||||
label##_done:
|
||||
|
||||
#define CALL_SP(func) \
|
||||
lea 0f, %sp ; \
|
||||
jmp func ; \
|
||||
0:
|
||||
|
||||
#define RET_SP \
|
||||
jmp *%sp
|
||||
|
||||
#define CALL_BP(func) \
|
||||
lea 0f, %bp ; \
|
||||
jmp func ; \
|
||||
0:
|
||||
|
||||
#define RET_BP \
|
||||
jmp *%bp
|
||||
111
src/northsouthbridge/sis/540/northbridge.c
Normal file
111
src/northsouthbridge/sis/540/northbridge.c
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
|
||||
/*
|
||||
* Bootstrap code for the INTEL
|
||||
* $Id$
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] =
|
||||
"$Id$";
|
||||
#endif
|
||||
|
||||
|
||||
#include <printk.h>
|
||||
#include <pciconf.h>
|
||||
#include <subr.h>
|
||||
#include <pci.h>
|
||||
#include <pci_ids.h>
|
||||
#include <northsouthbridge/sis/630/param.h>
|
||||
|
||||
/* these functions query the hardware to figure out how much ram is in
|
||||
* the machine. They then place that information in the parameter block.
|
||||
* This is kind of schizophrenic, but we do it this way because the
|
||||
* functions that actually set the registers are kind of hairy, and
|
||||
* we're not sure they can carry the full burden of also passing on
|
||||
* the size information to the rest of the bootstrap. Besides, querying
|
||||
* hardware for ram sizes is trivial.
|
||||
*/
|
||||
|
||||
/* table for calculate the DRAM size, the unit is Mega Bytes */
|
||||
const static int ramsizes[16] =
|
||||
{
|
||||
8, 32, 32, 64, 16, 64, 64, 128,
|
||||
32, 128, 128, 256, 16, 256, 256, 512
|
||||
};
|
||||
#define SIS630_BANKENABLE 0x63
|
||||
#define SIS630_BANK0 0x60
|
||||
#define SIS630_BANK1 0x61
|
||||
#define SIS630_BANK2 0x62
|
||||
#define SIS630_DIMM_LOCATION_FOR_SMA 0x65
|
||||
unsigned long sizeram()
|
||||
{
|
||||
struct pci_dev *pcidev;
|
||||
unsigned int dimm_slot, dimm_reg, sides;
|
||||
unsigned long total_size;
|
||||
u8 dram_status, dimm_status;
|
||||
u8 sma_enable, sma_size, sma_size_bits, sma_location;
|
||||
|
||||
// if ((pcidev = pci_find_device(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_630, NULL)) == NULL)
|
||||
// return 0;
|
||||
|
||||
if ((pcidev = pci_find_device(PCI_VENDOR_ID_SI, 0x0540, NULL)) == NULL)
|
||||
return 0;
|
||||
|
||||
pci_read_config_byte(pcidev, SIS630_BANKENABLE, &dram_status);
|
||||
dimm_status = dram_status & 0x7;
|
||||
sma_enable = dram_status & 0x80;
|
||||
|
||||
pci_read_config_byte(pcidev, SIS630_DIMM_LOCATION_FOR_SMA, &sma_location);
|
||||
sma_location &= 0x03;
|
||||
|
||||
/* compute Shared Menory Area (SMA) size in Mega Bytes */
|
||||
sma_size_bits = (dram_status >> 4) & 0x7;
|
||||
if (sma_size_bits > 5)
|
||||
// this is invalid!
|
||||
sma_size = 0;
|
||||
else {
|
||||
sma_size = (2 << sma_size_bits);
|
||||
}
|
||||
|
||||
for (dimm_slot = 0, total_size = 0, dimm_reg = SIS630_BANK0;
|
||||
dimm_reg <= SIS630_BANK2; dimm_slot++, dimm_reg++) {
|
||||
u8 regval;
|
||||
if ((dimm_status & (1 << dimm_slot)) == 0)
|
||||
/* this DIMM slot does not have SDRAM installed */
|
||||
continue;
|
||||
|
||||
pci_read_config_byte(pcidev, dimm_reg, ®val);
|
||||
|
||||
/* is this DIMM single or double sided ?? */
|
||||
if (regval & 0x20)
|
||||
sides = 2;
|
||||
else
|
||||
sides = 1;
|
||||
|
||||
/* low-order 4 bits are a ram size */
|
||||
total_size += (ramsizes[regval & 0xf] * sides);
|
||||
}
|
||||
|
||||
/* the total memory visible to the system is physical memory installed minus the
|
||||
amount used by VGA (sma_size) */
|
||||
total_size -= sma_size;
|
||||
|
||||
/* return the memory size in KB */
|
||||
total_size *= 1024;
|
||||
return total_size;
|
||||
}
|
||||
|
||||
#ifdef HAVE_FRAMEBUFFER
|
||||
void framebuffer_on()
|
||||
{
|
||||
unsigned long devfn = PCI_DEVFN(0, 0);
|
||||
u32 command;
|
||||
|
||||
/* enable legacy VGA register (0x3?4, 0x3?5), not actually needed */
|
||||
devfn = PCI_DEVFN(2, 0);
|
||||
pcibios_read_config_dword(0, devfn, 0x3e, &command);
|
||||
command |= 0x08;
|
||||
pcibios_write_config_dword(0, devfn, 0x3e, command);
|
||||
}
|
||||
#endif /* HAVE_FRAMEBUFFER */
|
||||
75
src/northsouthbridge/sis/540/raminit.inc
Normal file
75
src/northsouthbridge/sis/540/raminit.inc
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* raminit.inc: Setting registers to their recommended values for SiS 630.
|
||||
* Since we have inited the DRAM in IPL it is not neceressary
|
||||
* to do "raminit" here any more.
|
||||
*
|
||||
*
|
||||
* 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. SiS 630A1 Register Recommended Setting
|
||||
* Rev 0.97, Jan 7, 2000
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#define PCI_COMMAND_PORT 0xcf8
|
||||
#define PCI_DATA_PORT 0xcfc
|
||||
|
||||
#define NORTH_BRIDGE_BASE_ADDR 0x80000000
|
||||
|
||||
/* set new stack */
|
||||
movl $_estack, %esp
|
||||
|
||||
register_setting_start:
|
||||
movl $northbridge_init_table, %esi
|
||||
movl $(northbridge_init_table_end - northbridge_init_table), %ecx
|
||||
shrl $0x01, %ecx
|
||||
|
||||
init_northbridge:
|
||||
lodsw (%esi), %ax # load the register address/value to %ax
|
||||
xchgb %al, %ah # exchange address/values for write_common
|
||||
call write_northbridge_register
|
||||
loopnz init_northbridge
|
||||
|
||||
jmp register_setting_end
|
||||
|
||||
write_northbridge_register:
|
||||
/* Input: AH - register number. AL - register value. */
|
||||
movl $NORTH_BRIDGE_BASE_ADDR, %edx
|
||||
|
||||
write_common:
|
||||
movl %eax, %ebx # Save %eax to %ebx.
|
||||
|
||||
movzbl %bh, %eax # add register address to
|
||||
addl %edx, %eax # PCI base address
|
||||
|
||||
movw $PCI_COMMAND_PORT, %dx
|
||||
outl %eax, %dx
|
||||
|
||||
movw $PCI_DATA_PORT, %dx
|
||||
andb $0x03, %al
|
||||
addb %al, %dl
|
||||
movb %bl, %al
|
||||
outb %al, %dx
|
||||
ret # End of write_[lpc|pci]_reg
|
||||
|
||||
#include "540_regs.inc"
|
||||
|
||||
register_setting_end:
|
||||
159
src/northsouthbridge/sis/540/southbridge.c
Normal file
159
src/northsouthbridge/sis/540/southbridge.c
Normal file
|
|
@ -0,0 +1,159 @@
|
|||
|
||||
/*
|
||||
* Bootstrap code for the INTEL
|
||||
* $Id$
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] =
|
||||
"$Id$";
|
||||
#endif
|
||||
|
||||
|
||||
#include <printk.h>
|
||||
#include <pciconf.h>
|
||||
#include <subr.h>
|
||||
#include <pci.h>
|
||||
#include <pci_ids.h>
|
||||
#include <northsouthbridge/sis/630/param.h>
|
||||
#include <cpu/p5/io.h>
|
||||
|
||||
void keyboard_on()
|
||||
{
|
||||
u8 regval;
|
||||
struct pci_dev *pcidev;
|
||||
|
||||
/* turn on sis630 keyboard/mouse controller */
|
||||
pcidev = pci_find_device(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503, (void *)NULL);
|
||||
if (pcidev != NULL) {
|
||||
/* Register 0x47, Keyboard Controller */
|
||||
pci_read_config_byte(pcidev, 0x47, ®val);
|
||||
/* enable both integrated keyboard and PS/2 mouse controller */
|
||||
regval |= 0x0c;
|
||||
pci_write_config_byte(pcidev, 0x47, regval);
|
||||
}
|
||||
pc_keyboard_init();
|
||||
}
|
||||
|
||||
void nvram_on()
|
||||
{
|
||||
struct pci_dev *pcidev;
|
||||
|
||||
/* turn on sis540 nvram. */
|
||||
pcidev = pci_find_device(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503, (void *)NULL);
|
||||
if (pcidev != NULL) {
|
||||
/* Enable FFF80000 to FFFFFFFF decode. You have to also enable
|
||||
PCI Posted write for devices on sourthbridge */
|
||||
pci_write_config_byte(pcidev, 0x40, 0x33);
|
||||
/* Flash can be flashed */
|
||||
pci_write_config_byte(pcidev, 0x45, 0x40);
|
||||
DBG("Enabled in SIS 503 regs 0x40 and 0x45\n");
|
||||
|
||||
}
|
||||
DBG("Now try to turn off shadow\n");
|
||||
#ifdef USE_DOC_MIL
|
||||
/* turn off nvram shadow in 0xc0000 ~ 0xfffff, i.e. accessing segment C - F
|
||||
is actually to the DRAM not NVRAM. For 512KB NVRAM case, this one should be
|
||||
disabled */
|
||||
pcidev = pci_find_device(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_540, (void *)NULL);
|
||||
DBG("device for SiS 540 is 0x%x\n", pcidev);
|
||||
if (pcidev != NULL) {
|
||||
/* read cycle goes to System Memory */
|
||||
/* write cycle goest to System Memory */
|
||||
pci_write_config_word(pcidev, 0x70, 0xFFFF);
|
||||
pci_write_config_word(pcidev, 0x72, 0xFFFF);
|
||||
pci_write_config_word(pcidev, 0x74, 0xFFFF);
|
||||
pci_write_config_byte(pcidev, 0x76, 0xFF);
|
||||
DBG("Shadow memory disabled in SiS 540\n");
|
||||
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* serial_irq_fixup: Enable Serial Interrupt. Serial interrupt is the IRQ line from SiS 950
|
||||
* LPC to Host Controller. Serial IRQ is neceressary for devices on SiS 950
|
||||
* ie.e floppy, COM, LPT etc
|
||||
*/
|
||||
static void
|
||||
serial_irq_fixedup(void)
|
||||
{
|
||||
struct pci_dev *pcidev;
|
||||
|
||||
pcidev = pci_find_device(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503, (void *)NULL);
|
||||
if (pcidev != NULL) {
|
||||
/* enable Serial Interrupt (SIRQ) */
|
||||
pci_write_config_byte(pcidev, 0x70, 0x80);
|
||||
// skip the SMI, inta, etc. stuff.
|
||||
// enable IRQs 7 to 1
|
||||
pci_write_config_byte(pcidev, 0x72, 0xfd);
|
||||
// enable IRQs 15 to 8
|
||||
pci_write_config_byte(pcidev, 0x73, 0xff);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
acpi_fixup(void)
|
||||
{
|
||||
struct pci_dev *pcidev;
|
||||
|
||||
pcidev = pci_find_device(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503, (void *)NULL);
|
||||
if (pcidev != NULL) {
|
||||
unsigned char val;
|
||||
unsigned short acpibase = 0xc000, temp;
|
||||
int i;
|
||||
|
||||
// the following is to turn off software watchdogs.
|
||||
// we co-op the address space from c000-cfff here. Temporarily.
|
||||
// Later, we need a better way to do this.
|
||||
// But since Linux doesn't even understand this yet, no issue.
|
||||
// Set a base address for ACPI of 0xc000
|
||||
pci_read_config_word(pcidev, 0x74, &temp);
|
||||
|
||||
DBG("acpibase was 0x%x\n", temp);
|
||||
pci_write_config_word(pcidev, 0x74, acpibase);
|
||||
pci_read_config_word(pcidev, 0x74, &temp);
|
||||
DBG("acpibase is 0x%x\n", temp);
|
||||
|
||||
// now enable acpi
|
||||
pci_read_config_byte(pcidev, 0x40, &val);
|
||||
DBG("acpi enable reg was 0x%x\n", val);
|
||||
val |= 0x80;
|
||||
pci_write_config_byte(pcidev, 0x40, val);
|
||||
pci_read_config_byte(pcidev, 0x40, &val);
|
||||
DBG("acpi enable reg after set is 0x%x\n", val);
|
||||
DBG("acpi status: word at 0x56 is 0x%x\n",
|
||||
inw(acpibase+0x56));
|
||||
DBG("acpi status: byte at 0x4b is 0x%x\n",
|
||||
inb(acpibase + 0x4b));
|
||||
|
||||
// now that it's on, get in there and call off the dogs.
|
||||
// that's the recommended thing to do if MD40 iso on.
|
||||
outw(0, acpibase + 0x56);
|
||||
// does this help too?
|
||||
outb(0, acpibase + 0x4b);
|
||||
// ah ha! have to SET, NOT CLEAR!
|
||||
outb(0x40, acpibase + 0x56);
|
||||
DBG("acpibase + 0x56 is 0x%x\n",
|
||||
inb(acpibase+0x56));
|
||||
val &= (~0x80);
|
||||
pci_write_config_byte(pcidev, 0x40, val);
|
||||
pci_read_config_byte(pcidev, 0x40, &val);
|
||||
DBG("acpi disable reg after set is 0x%x\n", val);
|
||||
} else {
|
||||
printk(KERN_EMERG "Can't find south bridge!\n");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// simple fixup (which we hope can leave soon) for the sis southbridge part
|
||||
void
|
||||
final_southbridge_fixup()
|
||||
{
|
||||
struct pci_dev *pcidev;
|
||||
|
||||
serial_irq_fixedup();
|
||||
acpi_fixup();
|
||||
|
||||
DBG("Southbridge fixup done for SIS 503\n");
|
||||
}
|
||||
16
util/config/sis540.config
Normal file
16
util/config/sis540.config
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
# Sample config file for SiS 550 SoC with DoC Millennium (as root)
|
||||
arch i386
|
||||
# This will make a target directory of ./winfast
|
||||
target sis540
|
||||
|
||||
# SiS 550 SoC demo mainboard
|
||||
mainboard sis/540
|
||||
|
||||
# Use the internal VGA frame buffer device
|
||||
option HAVE_FRAMEBUFFER
|
||||
|
||||
# Path to your kernel (vmlinux)
|
||||
linux /usr/src/linux
|
||||
|
||||
# Kernel command line parameters
|
||||
commandline root=/dev/hda1 console=tty0 video=sisfb:1024x768-32@85,font:VGA8x16
|
||||
Loading…
Add table
Add a link
Reference in a new issue