From 1602dd5fddf3ada03508738218d760a7544ace50 Mon Sep 17 00:00:00 2001 From: Morgan Tsai Date: Mon, 29 Oct 2007 21:00:14 +0000 Subject: Thanks to the great efforts of Morgan Tsai of SiS we support the SiS966 southbridge now: From: Morgan Tsai It supports SiS761GX / SiS966 chipset, only for AMD K8 platform so far. Due to integrated VGA sharing system memory, some code in southbridge folder have to init northbridge. Copyright (C) 2007 Morgan Tsai Copyright (C) 2007 Silicon Integrated Systems Corp. (SiS) Change Log: Newly support GIGABYTE GA-2761GXDK CPU type: AMD AM2 socket Northbridge: SiS 761GX Southbridge: SiS 966 SuperIO: ITE8716F Signed-off-by: Morgan Tsai Acked-by: Stefan Reinauer git-svn-id: svn://svn.coreboot.org/coreboot/trunk@2902 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1 --- src/mainboard/sis/sis761/Config.lb | 341 ++++++++ src/mainboard/sis/sis761/Options.lb | 358 ++++++++ src/mainboard/sis/sis761/apc_auto.c | 132 +++ src/mainboard/sis/sis761/cache_as_ram_auto.c | 372 +++++++++ src/mainboard/sis/sis761/chip.h | 29 + src/mainboard/sis/sis761/cmos.layout | 119 +++ src/mainboard/sis/sis761/get_bus_conf.c | 148 ++++ src/mainboard/sis/sis761/irq_tables.c | 166 ++++ src/mainboard/sis/sis761/mainboard.c | 35 + src/mainboard/sis/sis761/mptable.c | 161 ++++ src/mainboard/sis/sis761/resourcemap.c | 283 +++++++ src/southbridge/sis/sis966/Config.lb | 37 + src/southbridge/sis/sis966/chip.h | 39 + src/southbridge/sis/sis966/id.inc | 36 + src/southbridge/sis/sis966/id.lds | 27 + src/southbridge/sis/sis966/romstrap.inc | 78 ++ src/southbridge/sis/sis966/romstrap.lds | 27 + src/southbridge/sis/sis966/sis966.c | 253 ++++++ src/southbridge/sis/sis966/sis966.h | 31 + src/southbridge/sis/sis966/sis966_aza.c | 501 ++++++++++++ src/southbridge/sis/sis966/sis966_early_ctrl.c | 60 ++ .../sis/sis966/sis966_early_setup_car.c | 429 ++++++++++ src/southbridge/sis/sis966/sis966_early_setup_ss.h | 222 +++++ src/southbridge/sis/sis966/sis966_early_smbus.c | 904 +++++++++++++++++++++ src/southbridge/sis/sis966/sis966_enable_rom.c | 41 + .../sis/sis966/sis966_enable_usbdebug_direct.c | 50 ++ src/southbridge/sis/sis966/sis966_ht.c | 56 ++ src/southbridge/sis/sis966/sis966_ide.c | 175 ++++ src/southbridge/sis/sis966/sis966_lpc.c | 451 ++++++++++ src/southbridge/sis/sis966/sis966_nic.c | 643 +++++++++++++++ src/southbridge/sis/sis966/sis966_pci.c | 109 +++ src/southbridge/sis/sis966/sis966_pcie.c | 86 ++ src/southbridge/sis/sis966/sis966_reset.c | 59 ++ src/southbridge/sis/sis966/sis966_sata.c | 301 +++++++ src/southbridge/sis/sis966/sis966_smbus.c | 154 ++++ src/southbridge/sis/sis966/sis966_smbus.h | 202 +++++ src/southbridge/sis/sis966/sis966_usb.c | 114 +++ src/southbridge/sis/sis966/sis966_usb2.c | 168 ++++ src/southbridge/sis/sis966/sisnb.c | 192 +++++ 39 files changed, 7589 insertions(+) create mode 100644 src/mainboard/sis/sis761/Config.lb create mode 100644 src/mainboard/sis/sis761/Options.lb create mode 100644 src/mainboard/sis/sis761/apc_auto.c create mode 100644 src/mainboard/sis/sis761/cache_as_ram_auto.c create mode 100644 src/mainboard/sis/sis761/chip.h create mode 100644 src/mainboard/sis/sis761/cmos.layout create mode 100644 src/mainboard/sis/sis761/get_bus_conf.c create mode 100644 src/mainboard/sis/sis761/irq_tables.c create mode 100644 src/mainboard/sis/sis761/mainboard.c create mode 100644 src/mainboard/sis/sis761/mptable.c create mode 100644 src/mainboard/sis/sis761/resourcemap.c create mode 100644 src/southbridge/sis/sis966/Config.lb create mode 100644 src/southbridge/sis/sis966/chip.h create mode 100644 src/southbridge/sis/sis966/id.inc create mode 100644 src/southbridge/sis/sis966/id.lds create mode 100644 src/southbridge/sis/sis966/romstrap.inc create mode 100644 src/southbridge/sis/sis966/romstrap.lds create mode 100644 src/southbridge/sis/sis966/sis966.c create mode 100644 src/southbridge/sis/sis966/sis966.h create mode 100644 src/southbridge/sis/sis966/sis966_aza.c create mode 100644 src/southbridge/sis/sis966/sis966_early_ctrl.c create mode 100644 src/southbridge/sis/sis966/sis966_early_setup_car.c create mode 100644 src/southbridge/sis/sis966/sis966_early_setup_ss.h create mode 100644 src/southbridge/sis/sis966/sis966_early_smbus.c create mode 100644 src/southbridge/sis/sis966/sis966_enable_rom.c create mode 100644 src/southbridge/sis/sis966/sis966_enable_usbdebug_direct.c create mode 100644 src/southbridge/sis/sis966/sis966_ht.c create mode 100644 src/southbridge/sis/sis966/sis966_ide.c create mode 100644 src/southbridge/sis/sis966/sis966_lpc.c create mode 100644 src/southbridge/sis/sis966/sis966_nic.c create mode 100644 src/southbridge/sis/sis966/sis966_pci.c create mode 100644 src/southbridge/sis/sis966/sis966_pcie.c create mode 100644 src/southbridge/sis/sis966/sis966_reset.c create mode 100644 src/southbridge/sis/sis966/sis966_sata.c create mode 100644 src/southbridge/sis/sis966/sis966_smbus.c create mode 100644 src/southbridge/sis/sis966/sis966_smbus.h create mode 100644 src/southbridge/sis/sis966/sis966_usb.c create mode 100644 src/southbridge/sis/sis966/sis966_usb2.c create mode 100644 src/southbridge/sis/sis966/sisnb.c (limited to 'src') diff --git a/src/mainboard/sis/sis761/Config.lb b/src/mainboard/sis/sis761/Config.lb new file mode 100644 index 0000000000..46a847f769 --- /dev/null +++ b/src/mainboard/sis/sis761/Config.lb @@ -0,0 +1,341 @@ +## +## This file is part of the LinuxBIOS project. +## +## Copyright (C) 2007 AMD +## Written by Yinghai Lu for AMD. +## Copyright (C) 2007 Silicon Integrated Systems Corp. (SiS) +## Written by Morgan Tsai for SiS. +## +## 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +## + +## +## Compute the location and size of where this firmware image +## (linuxBIOS plus bootloader) will live in the boot rom chip. +## +if USE_FAILOVER_IMAGE + default ROM_SECTION_SIZE = FAILOVER_SIZE + default ROM_SECTION_OFFSET = ( ROM_SIZE - FAILOVER_SIZE ) +else + if USE_FALLBACK_IMAGE + default ROM_SECTION_SIZE = FALLBACK_SIZE + default ROM_SECTION_OFFSET = ( ROM_SIZE - FALLBACK_SIZE - FAILOVER_SIZE ) + else + default ROM_SECTION_SIZE = ( ROM_SIZE - FALLBACK_SIZE - FAILOVER_SIZE ) + default ROM_SECTION_OFFSET = 0 + end +end + +## +## Compute the start location and size size of +## The linuxBIOS bootloader. +## +default PAYLOAD_SIZE = ( ROM_SECTION_SIZE - ROM_IMAGE_SIZE ) +default CONFIG_ROM_PAYLOAD_START = (0xffffffff - ROM_SIZE + ROM_SECTION_OFFSET + 1) + +## +## Compute where this copy of linuxBIOS will start in the boot rom +## +default _ROMBASE = ( CONFIG_ROM_PAYLOAD_START + PAYLOAD_SIZE ) + +## +## Compute a range of ROM that can cached to speed up linuxBIOS, +## execution speed. +## +## XIP_ROM_SIZE must be a power of 2. +## XIP_ROM_BASE must be a multiple of XIP_ROM_SIZE +## +default XIP_ROM_SIZE=65536 + +if USE_FAILOVER_IMAGE + default XIP_ROM_BASE = ( _ROMBASE - XIP_ROM_SIZE + ROM_IMAGE_SIZE) +else + if USE_FALLBACK_IMAGE + default XIP_ROM_BASE = ( _ROMBASE - XIP_ROM_SIZE + ROM_IMAGE_SIZE + FAILOVER_SIZE) + else + default XIP_ROM_BASE = ( _ROMBASE - XIP_ROM_SIZE + ROM_IMAGE_SIZE) + end +end + +arch i386 end + +## +## Build the objects we have code for in this directory. +## + +driver mainboard.o +#needed by irq_tables and mptable and acpi_tables +object get_bus_conf.o + +if HAVE_MP_TABLE object mptable.o end +if HAVE_PIRQ_TABLE object irq_tables.o end +#object reset.o +if USE_DCACHE_RAM + + if CONFIG_USE_INIT + makerule ./cache_as_ram_auto.o + depends "$(MAINBOARD)/cache_as_ram_auto.c option_table.h" + action "$(CC) -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/cache_as_ram_auto.c -Os -nostdinc -nostdlib -fno-builtin -Wall -c -o $@" + end + else + makerule ./cache_as_ram_auto.inc + depends "$(MAINBOARD)/cache_as_ram_auto.c option_table.h" + action "$(CC) -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/cache_as_ram_auto.c -Os -nostdinc -nostdlib -fno-builtin -Wall -c -S -o $@" + action "perl -e 's/.rodata/.rom.data/g' -pi $@" + action "perl -e 's/.text/.section .rom.text/g' -pi $@" + end + end + +end + +if USE_FAILOVER_IMAGE +else + if CONFIG_AP_CODE_IN_CAR + makerule ./apc_auto.o + depends "$(MAINBOARD)/apc_auto.c option_table.h" + action "$(CC) -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/apc_auto.c -Os -nostdinc -nostdlib -fno-builtin -Wall -c -o $@" + end + ldscript /arch/i386/init/ldscript_apc.lb + end +end + + +## +## Build our 16 bit and 32 bit linuxBIOS entry code +## +if HAVE_FAILOVER_BOOT + if USE_FAILOVER_IMAGE + mainboardinit cpu/x86/16bit/entry16.inc + ldscript /cpu/x86/16bit/entry16.lds + end +else + if USE_FALLBACK_IMAGE + mainboardinit cpu/x86/16bit/entry16.inc + ldscript /cpu/x86/16bit/entry16.lds + end +end + +mainboardinit cpu/x86/32bit/entry32.inc + +if USE_DCACHE_RAM + if CONFIG_USE_INIT + ldscript /cpu/x86/32bit/entry32.lds + end + + if CONFIG_USE_INIT + ldscript /cpu/amd/car/cache_as_ram.lds + end +end + + +## +## Build our reset vector (This is where linuxBIOS is entered) +## +if HAVE_FAILOVER_BOOT + if USE_FAILOVER_IMAGE + mainboardinit cpu/x86/16bit/reset16.inc + ldscript /cpu/x86/16bit/reset16.lds + else + mainboardinit cpu/x86/32bit/reset32.inc + ldscript /cpu/x86/32bit/reset32.lds + end +else + if USE_FALLBACK_IMAGE + mainboardinit cpu/x86/16bit/reset16.inc + ldscript /cpu/x86/16bit/reset16.lds + else + mainboardinit cpu/x86/32bit/reset32.inc + ldscript /cpu/x86/32bit/reset32.lds + end +end + +## +## Include an id string (For safe flashing) +## +mainboardinit southbridge/sis/sis966/id.inc +ldscript /southbridge/sis/sis966/id.lds + +## +## ROMSTRAP table for MCP55 +## +if HAVE_FAILOVER_BOOT + if USE_FAILOVER_IMAGE + mainboardinit southbridge/sis/sis966/romstrap.inc + ldscript /southbridge/sis/sis966/romstrap.lds + end +else + if USE_FALLBACK_IMAGE + mainboardinit southbridge/sis/sis966/romstrap.inc + ldscript /southbridge/sis/sis966/romstrap.lds + end +end + +if USE_DCACHE_RAM + ## + ## Setup Cache-As-Ram + ## + mainboardinit cpu/amd/car/cache_as_ram.inc +end + +### +### This is the early phase of linuxBIOS startup +### Things are delicate and we test to see if we should +### failover to another image. +### +if HAVE_FAILOVER_BOOT + if USE_FAILOVER_IMAGE + if USE_DCACHE_RAM + ldscript /arch/i386/lib/failover_failover.lds + end + end +else + if USE_FALLBACK_IMAGE + if USE_DCACHE_RAM + ldscript /arch/i386/lib/failover.lds + end + end +end + +## +## Setup RAM +## +if USE_DCACHE_RAM + + if CONFIG_USE_INIT + initobject cache_as_ram_auto.o + else + mainboardinit ./cache_as_ram_auto.inc + end +end + +## +## Include the secondary Configuration files +## +if CONFIG_CHIP_NAME + config chip.h +end + +chip northbridge/amd/amdk8/root_complex + device apic_cluster 0 on + chip cpu/amd/socket_AM2 + device apic 0 on end + end + end + device pci_domain 0 on + chip northbridge/amd/amdk8 #mc0 + device pci 18.0 on + # devices on link 0, link 0 == LDT 0 + chip southbridge/sis/sis966 + device pci 0.0 on end # Northbridge + ################################################# + device pci 1.0 on # AGP bridge + chip drivers/pci/onboard # Integrated VGA + device pci 0.0 on end + register "rom_address" = "0xfff80000" + end + end + ################################################# + ## device pci 1.0 on end # PCIE + device pci 2.0 on # LPC + chip superio/ite/it8716f + device pnp 2e.0 off # Floppy + io 0x60 = 0x3f0 + irq 0x70 = 6 + drq 0x74 = 2 + end + device pnp 2e.1 on # Com1 + io 0x60 = 0x3f8 + irq 0x70 = 4 + end + device pnp 2e.2 off # Com2 + io 0x60 = 0x2f8 + irq 0x70 = 3 + end + device pnp 2e.3 off # Parallel Port + io 0x60 = 0x378 + irq 0x70 = 7 + end + device pnp 2e.4 on # EC + io 0x60 = 0x290 + io 0x62 = 0x230 + irq 0x70 = 9 + end + device pnp 2e.5 off # Keyboard + io 0x60 = 0x60 + io 0x62 = 0x64 + irq 0x70 = 1 + end + device pnp 2e.6 off # Mouse + irq 0x70 = 12 + end + device pnp 2e.8 off # MIDI + io 0x60 = 0x300 + irq 0x70 = 10 + end + device pnp 2e.9 off # GAME + io 0x60 = 0x220 + end + device pnp 2e.a off end # CIR + end + end + + device pci 2.5 on end # IDE (SiS5513) + device pci 2.6 off end # Modem (SiS7013) + device pci 2.7 off end # Audio (SiS7012) + device pci 3.0 on end # USB (SiS7001,USB1.1) + device pci 3.1 on end # USB (SiS7001,USB1.1) + device pci 3.3 on end # USB (SiS7002,USB2.0) + device pci 4.0 on end # NIC (SiS191) + device pci 5.0 on end # SATA (SiS1183) + device pci 6.0 off end # SB PCIE1 (SiS000A) + device pci 7.0 off end # SB PCIE2 (SiS000A) + device pci 9.0 off end # PCI E 6 + device pci a.0 off end # PCI E 5 + device pci b.0 off end # PCI E 4 + device pci c.0 off end # PCI E 3 + device pci d.0 off end # PCI E 2 + device pci e.0 off end # PCI E 1 + device pci f.0 on end # Hda + + register "ide0_enable" = "1" + register "ide1_enable" = "1" + register "sata0_enable" = "1" + register "sata1_enable" = "1" + #register "mac_eeprom_smbus" = "3" # 1: smbus under 2e.8, 2: SM0 3: SM1 + #register "mac_eeprom_addr" = "0x51" + end + end # device pci 18.0 + device pci 18.0 on end # Link 1 + device pci 18.0 on end + device pci 18.1 on end + device pci 18.2 on end + device pci 18.3 on end + end # mc0 + + end # PCI domain + +# chip drivers/generic/debug +# device pnp 0.0 off end # chip name +# device pnp 0.1 on end # pci_regs_all +# device pnp 0.2 on end # mem +# device pnp 0.3 off end # cpuid +# device pnp 0.4 on end # smbus_regs_all +# device pnp 0.5 off end # dual core msr +# device pnp 0.6 off end # cache size +# device pnp 0.7 off end # tsc +# device pnp 0.8 off end # io +# device pnp 0.9 off end # io +# end +end #root_complex diff --git a/src/mainboard/sis/sis761/Options.lb b/src/mainboard/sis/sis761/Options.lb new file mode 100644 index 0000000000..a7832bc078 --- /dev/null +++ b/src/mainboard/sis/sis761/Options.lb @@ -0,0 +1,358 @@ +## +## This file is part of the LinuxBIOS project. +## +## Copyright (C) 2007 AMD +## Written by Yinghai Lu for AMD. +## Copyright (C) 2007 Silicon Integrated Systems Corp. (SiS) +## Written by Morgan Tsai for SiS. +## +## 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +## + +uses HAVE_MP_TABLE +uses HAVE_PIRQ_TABLE +uses HAVE_ACPI_TABLES +uses ACPI_SSDTX_NUM +uses USE_FALLBACK_IMAGE +uses USE_FAILOVER_IMAGE +uses HAVE_FALLBACK_BOOT +uses HAVE_FAILOVER_BOOT +uses HAVE_HARD_RESET +uses IRQ_SLOT_COUNT +uses HAVE_OPTION_TABLE +uses CONFIG_MAX_CPUS +uses CONFIG_MAX_PHYSICAL_CPUS +uses CONFIG_LOGICAL_CPUS +uses CONFIG_IOAPIC +uses CONFIG_SMP +uses FALLBACK_SIZE +uses FAILOVER_SIZE +uses ROM_SIZE +uses ROM_SECTION_SIZE +uses ROM_IMAGE_SIZE +uses ROM_SECTION_SIZE +uses ROM_SECTION_OFFSET +uses CONFIG_ROM_PAYLOAD +uses CONFIG_ROM_PAYLOAD_START +uses CONFIG_COMPRESSED_PAYLOAD_NRV2B +uses CONFIG_COMPRESSED_PAYLOAD_LZMA +uses CONFIG_PRECOMPRESSED_PAYLOAD +uses PAYLOAD_SIZE +uses _ROMBASE +uses XIP_ROM_SIZE +uses XIP_ROM_BASE +uses STACK_SIZE +uses HEAP_SIZE +uses USE_OPTION_TABLE +uses LB_CKS_RANGE_START +uses LB_CKS_RANGE_END +uses LB_CKS_LOC +uses MAINBOARD_PART_NUMBER +uses MAINBOARD_VENDOR +uses MAINBOARD +uses MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID +uses MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID +uses LINUXBIOS_EXTRA_VERSION +uses _RAMBASE +uses TTYS0_BAUD +uses TTYS0_BASE +uses TTYS0_LCS +uses DEFAULT_CONSOLE_LOGLEVEL +uses MAXIMUM_CONSOLE_LOGLEVEL +uses MAINBOARD_POWER_ON_AFTER_POWER_FAIL +uses CONFIG_CONSOLE_SERIAL8250 +uses HAVE_INIT_TIMER +uses CONFIG_GDB_STUB +uses CONFIG_GDB_STUB +uses CROSS_COMPILE +uses CC +uses HOSTCC +uses OBJCOPY +uses CONFIG_CHIP_NAME +uses CONFIG_CONSOLE_VGA +uses CONFIG_USBDEBUG_DIRECT +uses CONFIG_PCI_ROM_RUN +uses HW_MEM_HOLE_SIZEK +uses HW_MEM_HOLE_SIZE_AUTO_INC +uses K8_HT_FREQ_1G_SUPPORT + +uses HT_CHAIN_UNITID_BASE +uses HT_CHAIN_END_UNITID_BASE +uses SB_HT_CHAIN_ON_BUS0 +uses SB_HT_CHAIN_UNITID_OFFSET_ONLY + +uses USE_DCACHE_RAM +uses DCACHE_RAM_BASE +uses DCACHE_RAM_SIZE +uses DCACHE_RAM_GLOBAL_VAR_SIZE +uses CONFIG_USE_INIT + +uses SERIAL_CPU_INIT + +uses ENABLE_APIC_EXT_ID +uses APIC_ID_OFFSET +uses LIFT_BSP_APIC_ID + +uses CONFIG_PCI_64BIT_PREF_MEM + +uses CONFIG_LB_MEM_TOPK + +uses CONFIG_AP_CODE_IN_CAR + +uses MEM_TRAIN_SEQ + +uses WAIT_BEFORE_CPUS_INIT + +uses CONFIG_USE_PRINTK_IN_CAR + +### +### Build options +### + +## +## ROM_SIZE is the size of boot ROM that this board will use. +## +default ROM_SIZE=524288 +#default ROM_SIZE=0x100000 + +## +## FALLBACK_SIZE is the amount of the ROM the complete fallback image will use +## +#default FALLBACK_SIZE=131072 +#default FALLBACK_SIZE=0x40000 + +#FALLBACK: 256K-4K +default FALLBACK_SIZE=0x3f000 +#FAILOVER: 4K +default FAILOVER_SIZE=0x01000 + +#more 1M for pgtbl +default CONFIG_LB_MEM_TOPK=2048 + +## +## Build code for the fallback boot +## +default HAVE_FALLBACK_BOOT=1 +default HAVE_FAILOVER_BOOT=1 + +## +## Build code to reset the motherboard from linuxBIOS +## +default HAVE_HARD_RESET=1 + +## +## Build code to export a programmable irq routing table +## +default HAVE_PIRQ_TABLE=1 +default IRQ_SLOT_COUNT=11 + +## +## Build code to export an x86 MP table +## Useful for specifying IRQ routing values +## +default HAVE_MP_TABLE=0 + +## ACPI tables will be included +default HAVE_ACPI_TABLES=0 + +## +## Build code to export a CMOS option table +## +default HAVE_OPTION_TABLE=1 + +## +## Move the default LinuxBIOS cmos range off of AMD RTC registers +## +default LB_CKS_RANGE_START=49 +default LB_CKS_RANGE_END=122 +default LB_CKS_LOC=123 + +## +## Build code for SMP support +## Only worry about 2 micro processors +## +default CONFIG_SMP=0 +default CONFIG_MAX_CPUS=2 +default CONFIG_MAX_PHYSICAL_CPUS=1 +default CONFIG_LOGICAL_CPUS=1 + +#default SERIAL_CPU_INIT=0 + +default ENABLE_APIC_EXT_ID=0 +default APIC_ID_OFFSET=0x10 +default LIFT_BSP_APIC_ID=1 + +#CHIP_NAME ? +default CONFIG_CHIP_NAME=1 + +#memory hole size, 0 mean disable, others will enable the hole, at that case if it is small than mmio_basek, it will use mmio_basek instead. +#2G +#default HW_MEM_HOLE_SIZEK=0x200000 +#1G +default HW_MEM_HOLE_SIZEK=0x100000 +#512M +#default HW_MEM_HOLE_SIZEK=0x80000 + +#make auto increase hole size to avoid hole_startk equal to basek so as to make some kernel happy +#default HW_MEM_HOLE_SIZE_AUTO_INC=1 + +#Opteron K8 1G HT Support +default K8_HT_FREQ_1G_SUPPORT=1 + +#VGA Console +default CONFIG_CONSOLE_VGA=1 +default CONFIG_PCI_ROM_RUN=1 + +#default CONFIG_USBDEBUG_DIRECT=0 + +#HT Unit ID offset, default is 1, the typical one, 0 mean only one HT device +default HT_CHAIN_UNITID_BASE=0 + +#real SB Unit ID, default is 0x20, mean dont touch it at last +#default HT_CHAIN_END_UNITID_BASE=0x6 + +#make the SB HT chain on bus 0, default is not (0) +default SB_HT_CHAIN_ON_BUS0=2 + +#only offset for SB chain?, default is yes(1) +default SB_HT_CHAIN_UNITID_OFFSET_ONLY=0 + +#allow capable device use that above 4G +#default CONFIG_PCI_64BIT_PREF_MEM=1 + +## +## enable CACHE_AS_RAM specifics +## +default USE_DCACHE_RAM=1 +default DCACHE_RAM_BASE=0xc8000 +default DCACHE_RAM_SIZE=0x08000 +default DCACHE_RAM_GLOBAL_VAR_SIZE=0x01000 +default CONFIG_USE_INIT=0 + +default CONFIG_AP_CODE_IN_CAR=0 +default MEM_TRAIN_SEQ=2 +default WAIT_BEFORE_CPUS_INIT=0 + +## +## Build code to setup a generic IOAPIC +## +default CONFIG_IOAPIC=1 + +## +## Clean up the motherboard id strings +## +default MAINBOARD_PART_NUMBER="SiS" +default MAINBOARD_VENDOR="SIS" +default MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID=0x1039 +default MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID=0x1234 + +### +### LinuxBIOS layout values +### + +## ROM_IMAGE_SIZE is the amount of space to allow linuxBIOS to occupy. +default ROM_IMAGE_SIZE = 65536 + +## +## Use a small 8K stack +## +default STACK_SIZE=0x2000 + +## +## Use a small 32K heap +## +default HEAP_SIZE=0x8000 + +## +## Only use the option table in a normal image +## +default USE_OPTION_TABLE = (!USE_FALLBACK_IMAGE) && (!USE_FAILOVER_IMAGE ) + +## +## LinuxBIOS C code runs at this location in RAM +## +default _RAMBASE=0x00100000 + +## +## Load the payload from the ROM +## +default CONFIG_ROM_PAYLOAD = 1 + +#default CONFIG_COMPRESSED_PAYLOAD_NRV2B = 1 + +### +### Defaults of options that you may want to override in the target config file +### + +## +## The default compiler +## +default CC="$(CROSS_COMPILE)gcc -m32" +default HOSTCC="gcc" + +## +## Disable the gdb stub by default +## +default CONFIG_GDB_STUB=0 + +## +## The Serial Console +## +default CONFIG_USE_PRINTK_IN_CAR=1 + +# To Enable the Serial Console +default CONFIG_CONSOLE_SERIAL8250=1 + +## Select the serial console baud rate +default TTYS0_BAUD=115200 +#default TTYS0_BAUD=57600 +#default TTYS0_BAUD=38400 +#default TTYS0_BAUD=19200 +#default TTYS0_BAUD=9600 +#default TTYS0_BAUD=4800 +#default TTYS0_BAUD=2400 +#default TTYS0_BAUD=1200 + +# Select the serial console base port +default TTYS0_BASE=0x3f8 + +# Select the serial protocol +# This defaults to 8 data bits, 1 stop bit, and no parity +default TTYS0_LCS=0x3 + +## +### Select the linuxBIOS loglevel +## +## EMERG 1 system is unusable +## ALERT 2 action must be taken immediately +## CRIT 3 critical conditions +## ERR 4 error conditions +## WARNING 5 warning conditions +## NOTICE 6 normal but significant condition +## INFO 7 informational +## DEBUG 8 debug-level messages +## SPEW 9 Way too many details + +## Request this level of debugging output +default DEFAULT_CONSOLE_LOGLEVEL=8 +## At a maximum only compile in this level of debugging +default MAXIMUM_CONSOLE_LOGLEVEL=8 + +## +## Select power on after power fail setting +default MAINBOARD_POWER_ON_AFTER_POWER_FAIL="MAINBOARD_POWER_ON" + +### End Options.lb +end diff --git a/src/mainboard/sis/sis761/apc_auto.c b/src/mainboard/sis/sis761/apc_auto.c new file mode 100644 index 0000000000..7e4eddaa5c --- /dev/null +++ b/src/mainboard/sis/sis761/apc_auto.c @@ -0,0 +1,132 @@ +/* + * This file is part of the LinuxBIOS project. + * + * Copyright (C) 2007 AMD + * Written by Yinghai Lu for AMD. + * Copyright (C) 2007 Silicon Integrated Systems Corp. (SiS) + * Written by Morgan Tsai for SiS. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#define ASSEMBLY 1 +#define __ROMCC__ + +#define RAMINIT_SYSINFO 1 +#define CACHE_AS_RAM_ADDRESS_DEBUG 0 + +#define SET_NB_CFG_54 1 + +//used by raminit +#define QRANK_DIMM_SUPPORT 1 + +#define K8_REV_F_SUPPORT_F0_F1_WORKAROUND 0 + +#include +#include +#include +#include +#include +#include +#include +#include "option_table.h" +#include "pc80/mc146818rtc_early.c" +#include "pc80/serial.c" + +#if CONFIG_USE_INIT == 0 + #include "lib/memcpy.c" +#endif + +#include "arch/i386/lib/console.c" + +#if 0 +static void post_code(uint8_t value) { +#if 1 + int i; + for(i=0;i<0x80000;i++) { + outb(value, 0x80); + } +#endif +} +#endif + +#include +#include "northbridge/amd/amdk8/raminit.h" +#include "cpu/amd/model_fxx/apic_timer.c" + +#include "lib/delay.c" + +//#include "cpu/x86/lapic/boot_cpu.c" +#include "northbridge/amd/amdk8/reset_test.c" + +#include "northbridge/amd/amdk8/debug.c" + +#include "southbridge/sis/sis966/sis966_early_ctrl.c" + +#include "northbridge/amd/amdk8/amdk8_f.h" + +#include "cpu/x86/mtrr.h" +#include "cpu/amd/mtrr.h" +#include "cpu/x86/tsc.h" + +#include "northbridge/amd/amdk8/amdk8_f_pci.c" +#include "northbridge/amd/amdk8/raminit_f_dqs.c" + +#include "cpu/amd/dualcore/dualcore.c" + +void hardwaremain(int ret_addr) +{ + struct sys_info *sysinfo = (DCACHE_RAM_BASE + DCACHE_RAM_SIZE - DCACHE_RAM_GLOBAL_VAR_SIZE); // in CACHE + struct sys_info *sysinfox = ((CONFIG_LB_MEM_TOPK<<10) - DCACHE_RAM_GLOBAL_VAR_SIZE); // in RAM + + struct node_core_id id; + + id = get_node_core_id_x(); + + //FIXME: for USBDEBUG_DIRECT you need to make sure dbg_info get assigned in AP + print_debug("CODE IN CACHE ON NODE:"); print_debug_hex8(id.nodeid); print_debug("\r\n"); + + train_ram(id.nodeid, sysinfo, sysinfox); + + /* + go back, but can not use stack any more, because we only keep ret_addr and can not restore esp, and ebp + */ + + __asm__ volatile ( + "movl %0, %%edi\n\t" + "jmp *%%edi\n\t" + :: "a"(ret_addr) + ); + + + +} +struct eregs { + uint32_t eax, ecx, edx, ebx, esp, ebp, esi, edi; + uint32_t vector; + uint32_t error_code; + uint32_t eip; + uint32_t cs; + uint32_t eflags; +}; + +void x86_exception(struct eregs *info) +{ + do { + hlt(); + } while(1); +} + + diff --git a/src/mainboard/sis/sis761/cache_as_ram_auto.c b/src/mainboard/sis/sis761/cache_as_ram_auto.c new file mode 100644 index 0000000000..732027adca --- /dev/null +++ b/src/mainboard/sis/sis761/cache_as_ram_auto.c @@ -0,0 +1,372 @@ +/* + * This file is part of the LinuxBIOS project. + * + * Copyright (C) 2007 AMD + * Written by Yinghai Lu for AMD. + * Copyright (C) 2007 Silicon Integrated Systems Corp. (SiS) + * Written by Morgan Tsai for SiS. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#define ASSEMBLY 1 +#define __ROMCC__ + +#define RAMINIT_SYSINFO 1 + +#define K8_ALLOCATE_IO_RANGE 1 +//#define K8_SCAN_PCI_BUS 1 + + +#define QRANK_DIMM_SUPPORT 1 + +#if CONFIG_LOGICAL_CPUS==1 +#define SET_NB_CFG_54 1 +#endif + +//used by init_cpus and fidvid +#define K8_SET_FIDVID 1 +//if we want to wait for core1 done before DQS training, set it to 0 +#define K8_SET_FIDVID_CORE0_ONLY 1 + +#if K8_REV_F_SUPPORT == 1 +#define K8_REV_F_SUPPORT_F0_F1_WORKAROUND 0 +#endif + +#define DBGP_DEFAULT 7 + +#include +#include +#include +#include +#include +#include +#include +#include "option_table.h" +#include "pc80/mc146818rtc_early.c" + +#if USE_FAILOVER_IMAGE==0 +#include "pc80/serial.c" +#include "arch/i386/lib/console.c" +#if CONFIG_USBDEBUG_DIRECT +#include "southbridge/sis/sis966/sis966_enable_usbdebug_direct.c" +#include "pc80/usbdebug_direct_serial.c" +#endif +#include "ram/ramtest.c" + +#include + +#include "southbridge/sis/sis966/sis966_early_smbus.c" +#include "southbridge/sis/sis966/sis966_enable_rom.c" +#include "northbridge/amd/amdk8/raminit.h" +#include "cpu/amd/model_fxx/apic_timer.c" +#include "lib/delay.c" + +#endif + +#include "cpu/x86/lapic/boot_cpu.c" +#include "northbridge/amd/amdk8/reset_test.c" +#include "superio/ite/it8716f/it8716f_early_serial.c" +#include "superio/ite/it8716f/it8716f_early_init.c" + +#if USE_FAILOVER_IMAGE==0 + +#include "cpu/x86/bist.h" + +#if CONFIG_USE_INIT == 0 + #include "lib/memcpy.c" +#endif + +#include "northbridge/amd/amdk8/debug.c" + +#include "cpu/amd/mtrr/amd_earlymtrr.c" + +#include "northbridge/amd/amdk8/setup_resource_map.c" + +#define SERIAL_DEV PNP_DEV(0x2e, IT8716F_SP1) + +#include "southbridge/sis/sis966/sis966_early_ctrl.c" + +static void memreset_setup(void) +{ +} + +static void memreset(int controllers, const struct mem_controller *ctrl) +{ +} + +static inline void activate_spd_rom(const struct mem_controller *ctrl) +{ + /* nothing to do */ +} + +static inline int spd_read_byte(unsigned device, unsigned address) +{ + return smbus_read_byte(device, address); +} + +#include "northbridge/amd/amdk8/amdk8_f.h" +#include "northbridge/amd/amdk8/coherent_ht.c" + +#include "northbridge/amd/amdk8/incoherent_ht.c" + +#include "northbridge/amd/amdk8/raminit_f.c" + +#include "sdram/generic_sdram.c" + +#include "resourcemap.c" + +#include "cpu/amd/dualcore/dualcore.c" + +#define SIS966_NUM 1 +#define SIS966_USE_NIC 1 +#define SIS966_USE_AZA 1 + +#define SIS966_PCI_E_X_0 0 + +#define SIS966_MB_SETUP \ + RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0+37, 0x00, 0x44,/* GPIO38 PCI_REQ3 */ \ + RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0+38, 0x00, 0x44,/* GPIO39 PCI_GNT3 */ \ + RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0+39, 0x00, 0x44,/* GPIO40 PCI_GNT2 */ \ + RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0+40, 0x00, 0x44,/* GPIO41 PCI_REQ2 */ \ + RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0+59, 0x00, 0x60,/* GPIP60 FANCTL0 */ \ + RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0+60, 0x00, 0x60,/* GPIO61 FANCTL1 */ + +#include "southbridge/sis/sis966/sis966_early_setup_ss.h" +#include "southbridge/sis/sis966/sis966_early_setup_car.c" + +#include "cpu/amd/car/copy_and_run.c" + +#include "cpu/amd/car/post_cache_as_ram.c" + +#include "cpu/amd/model_fxx/init_cpus.c" + +#include "cpu/amd/model_fxx/fidvid.c" + +#endif + +#if ((HAVE_FAILOVER_BOOT==1) && (USE_FAILOVER_IMAGE == 1)) || ((HAVE_FAILOVER_BOOT==0) && (USE_FALLBACK_IMAGE == 1)) + +#include "southbridge/sis/sis966/sis966_enable_rom.c" +#include "northbridge/amd/amdk8/early_ht.c" + + +static void sio_setup(void) +{ + + unsigned value; + uint32_t dword; + uint8_t byte; + + byte = pci_read_config8(PCI_DEV(0, SIS966_DEVN_BASE+1 , 0), 0x7b); + byte |= 0x20; + pci_write_config8(PCI_DEV(0, SIS966_DEVN_BASE+1 , 0), 0x7b, byte); + + dword = pci_read_config32(PCI_DEV(0, SIS966_DEVN_BASE+1 , 0), 0xa0); + dword |= (1<<0); + pci_write_config32(PCI_DEV(0, SIS966_DEVN_BASE+1 , 0), 0xa0, dword); + + dword = pci_read_config32(PCI_DEV(0, SIS966_DEVN_BASE+1 , 0), 0xa4); + dword |= (1<<16); + pci_write_config32(PCI_DEV(0, SIS966_DEVN_BASE+1 , 0), 0xa4, dword); +} + +void failover_process(unsigned long bist, unsigned long cpu_init_detectedx) +{ + unsigned last_boot_normal_x = last_boot_normal(); + + /* Is this a cpu only reset? or Is this a secondary cpu? */ + if ((cpu_init_detectedx) || (!boot_cpu())) { + if (last_boot_normal_x) { + goto normal_image; + } else { + goto fallback_image; + } + } + + /* Nothing special needs to be done to find bus 0 */ + /* Allow the HT devices to be found */ + + enumerate_ht_chain(); + + sio_setup(); + + /* Setup the sis966 */ + sis966_enable_rom(); + + /* Is this a deliberate reset by the bios */ + if (bios_reset_detected() && last_boot_normal_x) { + goto normal_image; + } + /* This is the primary cpu how should I boot? */ + else if (do_normal_boot()) { + goto normal_image; + } + else { + goto fallback_image; + } + normal_image: + __asm__ volatile ("jmp __normal_image" + : /* outputs */ + : "a" (bist), "b" (cpu_init_detectedx) /* inputs */ + ); + + fallback_image: +#if HAVE_FAILOVER_BOOT==1 + __asm__ volatile ("jmp __fallback_image" + : /* outputs */ + : "a" (bist), "b" (cpu_init_detectedx) /* inputs */ + ) +#endif + ; +} +#endif +void real_main(unsigned long bist, unsigned long cpu_init_detectedx); + +void cache_as_ram_main(unsigned long bist, unsigned long cpu_init_detectedx) +{ +#if HAVE_FAILOVER_BOOT==1 + #if USE_FAILOVER_IMAGE==1 + failover_process(bist, cpu_init_detectedx); + #else + real_main(bist, cpu_init_detectedx); + #endif +#else + #if USE_FALLBACK_IMAGE == 1 + failover_process(bist, cpu_init_detectedx); + #endif + real_main(bist, cpu_init_detectedx); +#endif +} + +#if USE_FAILOVER_IMAGE==0 + +void real_main(unsigned long bist, unsigned long cpu_init_detectedx) +{ + static const uint16_t spd_addr [] = { + (0xa<<3)|0, (0xa<<3)|2, 0, 0, + (0xa<<3)|1, (0xa<<3)|3, 0, 0, +#if CONFIG_MAX_PHYSICAL_CPUS > 1 + (0xa<<3)|4, (0xa<<3)|6, 0, 0, + (0xa<<3)|5, (0xa<<3)|7, 0, 0, +#endif + }; + + struct sys_info *sysinfo = (DCACHE_RAM_BASE + DCACHE_RAM_SIZE - DCACHE_RAM_GLOBAL_VAR_SIZE); + + int needs_reset = 0; + unsigned bsp_apicid = 0; + + if (bist == 0) { + bsp_apicid = init_cpus(cpu_init_detectedx, sysinfo); + } + + pnp_enter_ext_func_mode(SERIAL_DEV); + pnp_write_config(SERIAL_DEV, 0x23, 0); + it8716f_enable_dev(SERIAL_DEV, TTYS0_BASE); + pnp_exit_ext_func_mode(SERIAL_DEV); + + setup_mb_resource_map(); + + uart_init(); + + /* Halt if there was a built in self test failure */ + report_bist_failure(bist); + + +#if CONFIG_USBDEBUG_DIRECT + sis966_enable_usbdebug_direct(DBGP_DEFAULT); + early_usbdebug_direct_init(); +#endif + console_init(); + print_debug("*sysinfo range: ["); print_debug_hex32(sysinfo); print_debug(","); print_debug_hex32((unsigned long)sysinfo+sizeof(struct sys_info)); print_debug(")\r\n"); + + print_debug("bsp_apicid="); print_debug_hex8(bsp_apicid); print_debug("\r\n"); + +#if MEM_TRAIN_SEQ == 1 + set_sysinfo_in_ram(0); // in BSP so could hold all ap until sysinfo is in ram +#endif + setup_coherent_ht_domain(); // routing table and start other core0 + + wait_all_core0_started(); +#if CONFIG_LOGICAL_CPUS==1 + // It is said that we should start core1 after all core0 launched + /* becase optimize_link_coherent_ht is moved out from setup_coherent_ht_domain, + * So here need to make sure last core0 is started, esp for two way system, + * (there may be apic id conflicts in that case) + */ + start_other_cores(); + wait_all_other_cores_started(bsp_apicid); +#endif + + /* it will set up chains and store link pair for optimization later */ + ht_setup_chains_x(sysinfo); // it will init sblnk and sbbusn, nodes, sbdn + +#if K8_SET_FIDVID == 1 + + { + msr_t msr; + msr=rdmsr(0xc0010042); + print_debug("begin msr fid, vid "); print_debug_hex32( msr.hi ); print_debug_hex32(msr.lo); print_debug("\r\n"); + + } + + enable_fid_change(); + + enable_fid_change_on_sb(sysinfo->sbbusn, sysinfo->sbdn); + + init_fidvid_bsp(bsp_apicid); + + // show final fid and vid + { + msr_t msr; + msr=rdmsr(0xc0010042); + print_debug("end msr fid, vid "); print_debug_hex32( msr.hi ); print_debug_hex32(msr.lo); print_debug("\r\n"); + + } +#endif + + needs_reset |= optimize_link_coherent_ht(); + needs_reset |= optimize_link_incoherent_ht(sysinfo); + needs_reset |= sis966_early_setup_x(); + + // fidvid change will issue one LDTSTOP and the HT change will be effective too + if (needs_reset) { + print_info("ht reset -\r\n"); + soft_reset(); + } + allow_all_aps_stop(bsp_apicid); + + //It's the time to set ctrl in sysinfo now; + fill_mem_ctrl(sysinfo->nodes, sysinfo->ctrl, spd_addr); + + sis_init_stage1(); + enable_smbus(); + + memreset_setup(); + + //do we need apci timer, tsc...., only debug need it for better output + /* all ap stopped? */ +// init_timer(); // Need to use TMICT to synconize FID/VID + + sdram_initialize(sysinfo->nodes, sysinfo->ctrl, sysinfo); + + sis_init_stage2(); + post_cache_as_ram(); // bsp swtich stack to ram and copy sysinfo ram now + +} + + +#endif diff --git a/src/mainboard/sis/sis761/chip.h b/src/mainboard/sis/sis761/chip.h new file mode 100644 index 0000000000..8d6d00cac6 --- /dev/null +++ b/src/mainboard/sis/sis761/chip.h @@ -0,0 +1,29 @@ +/* + * This file is part of the LinuxBIOS project. + * + * Copyright (C) 2007 AMD + * Written by Yinghai Lu for AMD. + * Copyright (C) 2007 Silicon Integrated Systems Corp. (SiS) + * Written by Morgan Tsai for SiS. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +extern struct chip_operations mainboard_sis_sis761_ops; + +struct mainboard_sis_sis761_config { +// int fixup_scsi; +// int fixup_vga; +}; diff --git a/src/mainboard/sis/sis761/cmos.layout b/src/mainboard/sis/sis761/cmos.layout new file mode 100644 index 0000000000..84a5c52278 --- /dev/null +++ b/src/mainboard/sis/sis761/cmos.layout @@ -0,0 +1,119 @@ +## +## This file is part of the LinuxBIOS project. +## +## Copyright (C) 2007 AMD +## Written by Yinghai Lu for AMD. +## +## 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +## + +entries + +#start-bit length config config-ID name +#0 8 r 0 seconds +#8 8 r 0 alarm_seconds +#16 8 r 0 minutes +#24 8 r 0 alarm_minutes +#32 8 r 0 hours +#40 8 r 0 alarm_hours +#48 8 r 0 day_of_week +#56 8 r 0 day_of_month +#64 8 r 0 month +#72 8 r 0 year +#80 4 r 0 rate_select +#84 3 r 0 REF_Clock +#87 1 r 0 UIP +#88 1 r 0 auto_switch_DST +#89 1 r 0 24_hour_mode +#90 1 r 0 binary_values_enable +#91 1 r 0 square-wave_out_enable +#92 1 r 0 update_finished_enable +#93 1 r 0 alarm_interrupt_enable +#94 1 r 0 periodic_interrupt_enable +#95 1 r 0 disable_clock_updates +#96 288 r 0 temporary_filler +0 384 r 0 reserved_memory +384 1 e 4 boot_option +385 1 e 4 last_boot +386 1 e 1 ECC_memory +388 4 r 0 reboot_bits +392 3 e 5 baud_rate +395 1 e 1 hw_scrubber +396 1 e 1 interleave_chip_selects +397 2 e 8 max_mem_clock +399 1 e 2 dual_core +400 1 e 1 power_on_after_fail +412 4 e 6 debug_level +416 4 e 7 boot_first +420 4 e 7 boot_second +424 4 e 7 boot_third +428 4 h 0 boot_index +432 8 h 0 boot_countdown +440 4 e 9 slow_cpu +444 1 e 1 nmi +445 1 e 1 iommu +728 256 h 0 user_data +984 16 h 0 check_sum +# Reserve the extended AMD configuration registers +1000 24 r 0 reserved_memory + + + +enumerations + +#ID value text +1 0 Disable +1 1 Enable +2 0 Enable +2 1 Disable +4 0 Fallback +4 1 Normal +5 0 115200 +5 1 57600 +5 2 38400 +5 3 19200 +5 4 9600 +5 5 4800 +5 6 2400 +5 7 1200 +6 6 Notice +6 7 Info +6 8 Debug +6 9 Spew +7 0 Network +7 1 HDD +7 2 Floppy +7 8 Fallback_Network +7 9 Fallback_HDD +7 10 Fallback_Floppy +#7 3 ROM +8 0 200Mhz +8 1 166Mhz +8 2 133Mhz +8 3 100Mhz +9 0 off +9 1 87.5% +9 2 75.0% +9 3 62.5% +9 4 50.0% +9 5 37.5% +9 6 25.0% +9 7 12.5% + +checksums + +checksum 392 983 984 + + diff --git a/src/mainboard/sis/sis761/get_bus_conf.c b/src/mainboard/sis/sis761/get_bus_conf.c new file mode 100644 index 0000000000..d8b0c0ab5a --- /dev/null +++ b/src/mainboard/sis/sis761/get_bus_conf.c @@ -0,0 +1,148 @@ +/* + * This file is part of the LinuxBIOS project. + * + * Copyright (C) 2007 AMD + * Written by Yinghai Lu for AMD. + * Copyright (C) 2007 Silicon Integrated Systems Corp. (SiS) + * Written by Morgan Tsai for SiS. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#if CONFIG_LOGICAL_CPUS==1 +#include +#endif + +#include + + +// Global variables for MB layouts and these will be shared by irqtable mptable and acpi_tables +//busnum is default + unsigned char bus_isa; + unsigned char bus_sis966[8]; //1 + unsigned apicid_sis966; + + +unsigned pci1234x[] = +{ //Here you only need to set value in pci1234 for HT-IO that could be installed or not + //You may need to preset pci1234 for HTIO board, please refer to src/northbridge/amd/amdk8/get_sblk_pci1234.c for detail + 0x0000ff0, +// 0x0000ff0, +// 0x0000ff0, +// 0x0000ff0, +// 0x0000ff0, +// 0x0000ff0, +// 0x0000ff0, +// 0x0000ff0 +}; +unsigned hcdnx[] = +{ //HT Chain device num, actually it is unit id base of every ht device in chain, assume every chain only have 4 ht device at most + 0x20202020, +// 0x20202020, +// 0x20202020, +// 0x20202020, +// 0x20202020, +// 0x20202020, +// 0x20202020, +// 0x20202020, +}; +unsigned bus_type[256]; + +extern void get_sblk_pci1234(void); + +static unsigned get_bus_conf_done = 0; + +void get_bus_conf(void) +{ + + unsigned apicid_base; + unsigned sbdn; + + device_t dev; + int i, j; + + if(get_bus_conf_done==1) return; //do it only once + + get_bus_conf_done = 1; + + sysconf.hc_possible_num = sizeof(pci1234x)/sizeof(pci1234x[0]); + for(i=0;i> 16) & 0xff; + + bus_type[bus_sis966[0]] = 1; + + /* SIS966 */ + dev = dev_find_slot(bus_sis966[0], PCI_DEVFN(sbdn + 0x06,0)); + if (dev) { + bus_sis966[1] = pci_read_config8(dev, PCI_SECONDARY_BUS); + bus_sis966[2] = pci_read_config8(dev, PCI_SUBORDINATE_BUS); + bus_sis966[2]++; + for(j=bus_sis966[1];j for AMD. + * Copyright (C) 2007 Silicon Integrated Systems Corp. (SiS) + * Written by Morgan Tsai for SiS. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* This file was generated by getpir.c, do not modify! + (but if you do, please run checkpir on it to verify) + Contains the IRQ Routing Table dumped directly from your memory , wich BIOS sets up + + Documentation at : http://www.microsoft.com/hwdev/busbios/PCIIRQ.HTM +*/ +#include +#include +#include +#include +#include + +#include + +static void write_pirq_info(struct irq_info *pirq_info, uint8_t bus, uint8_t devfn, uint8_t link0, uint16_t bitmap0, + uint8_t link1, uint16_t bitmap1, uint8_t link2, uint16_t bitmap2,uint8_t link3, uint16_t bitmap3, + uint8_t slot, uint8_t rfu) +{ + pirq_info->bus = bus; + pirq_info->devfn = devfn; + pirq_info->irq[0].link = link0; + pirq_info->irq[0].bitmap = bitmap0; + pirq_info->irq[1].link = link1; + pirq_info->irq[1].bitmap = bitmap1; + pirq_info->irq[2].link = link2; + pirq_info->irq[2].bitmap = bitmap2; + pirq_info->irq[3].link = link3; + pirq_info->irq[3].bitmap = bitmap3; + pirq_info->slot = slot; + pirq_info->rfu = rfu; +} +extern unsigned char bus_isa; +extern unsigned char bus_sis966[8]; //1 + +unsigned long write_pirq_routing_table(unsigned long addr) +{ + + struct irq_routing_table *pirq; + struct irq_info *pirq_info; + unsigned slot_num; + uint8_t *v; + unsigned sbdn; + + uint8_t sum=0; + int i; + + get_bus_conf(); // it will find out all bus num and apic that share with mptable.c and mptable.c and acpi_tables.c + sbdn = sysconf.sbdn; + + /* Align the table to be 16 byte aligned. */ + addr += 15; + addr &= ~15; + + /* This table must be betweeen 0xf0000 & 0x100000 */ + printk_info("Writing IRQ routing tables to 0x%x...", addr); + + pirq = (void *)(addr); + v = (uint8_t *)(addr); + + pirq->signature = PIRQ_SIGNATURE; + pirq->version = PIRQ_VERSION; + + pirq->rtr_bus = bus_sis966[0]; + pirq->rtr_devfn = ((sbdn+6)<<3)|0; + + pirq->exclusive_irqs = 0; + + pirq->rtr_vendor = 0x10de; + pirq->rtr_device = 0x0370; + + pirq->miniport_data = 0; + + memset(pirq->rfu, 0, sizeof(pirq->rfu)); + + pirq_info = (void *) ( &pirq->checksum + 1); + slot_num = 0; + + { + device_t dev; + dev = dev_find_slot(0, PCI_DEVFN(2,0)); + if (dev) { + /* initialize PCI interupts - these assignments depend + on the PCB routing of PINTA-D + + PINTA = IRQ10 + PINTB = IRQ11 + PINTC = IRQ5 + PINTD = IRQ5 + PINTE = IRQ11 + PINTF = IRQ5 + PINTG = IRQ10 + PINTH = IRQ5 + + */ + int i; + uint8_t reg[8]={0x41,0x42,0x43,0x44,0x60,0x61,0x62,0x63}; + uint8_t irq[8]={0x0A,0X0B,0X05,0X05,0X0B,0X05,0X0A,0X0A}; + + for(i=0;i<8;i++) + pci_write_config8(dev, reg[i], irq[i]); + } + + printk_debug("Setting Onboard SiS Southbridge\n"); +// dev = dev_find_slot(0, PCI_DEVFN(2,5)); // 5513 (IDE) +// pci_write_config8(dev, 0x3C, 0x0A); + dev = dev_find_slot(0, PCI_DEVFN(3,0)); // USB 1.1 -1 + pci_write_config8(dev, 0x3C, 0x0B); + dev = dev_find_slot(0, PCI_DEVFN(3,1)); // USB 1.1 -2 + pci_write_config8(dev, 0x3C, 0x05); + dev = dev_find_slot(0, PCI_DEVFN(3,3)); // USB 2.0 + pci_write_config8(dev, 0x3C, 0x0A); + dev = dev_find_slot(0, PCI_DEVFN(4,0)); // 191 (LAN) + pci_write_config8(dev, 0x3C, 0x05); + dev = dev_find_slot(0, PCI_DEVFN(5,0)); // 1183 (SATA) + pci_write_config8(dev, 0x3C, 0x0B); +// dev = dev_find_slot(0, PCI_DEVFN(6,0)); // PCI-E +// pci_write_config8(dev, 0x3C, 0x0A); +// dev = dev_find_slot(0, PCI_DEVFN(7,0)); // PCI-E +// pci_write_config8(dev, 0x3C, 0x0A); + dev = dev_find_slot(0, PCI_DEVFN(15,0)); // Azalia + pci_write_config8(dev, 0x3C, 0x05); + } + +//pci bridge + write_pirq_info(pirq_info, bus_sis966[0], ((sbdn+6)<<3)|0, 0x1, 0xdef8, 0x2, 0xdef8, 0x3, 0xdef8, 0x4, 0xdef8, 0, 0); + pirq_info++; slot_num++; + + pirq->size = 32 + 16 * slot_num; + + for (i = 0; i < pirq->size; i++) + sum += v[i]; + + sum = pirq->checksum - sum; + + if (sum != pirq->checksum) { + pirq->checksum = sum; + } + + printk_info("done.\n"); + + return (unsigned long) pirq_info; + +} diff --git a/src/mainboard/sis/sis761/mainboard.c b/src/mainboard/sis/sis761/mainboard.c new file mode 100644 index 0000000000..9e21efdce8 --- /dev/null +++ b/src/mainboard/sis/sis761/mainboard.c @@ -0,0 +1,35 @@ +/* + * This file is part of the LinuxBIOS project. + * + * Copyright (C) 2007 AMD + * Written by Yinghai Lu for AMD. + * Copyright (C) 2007 Silicon Integrated Systems Corp. (SiS) + * Written by Morgan Tsai for SiS. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include "chip.h" + +#if CONFIG_CHIP_NAME == 1 +struct chip_operations mainboard_sis_sis761_ops = { + CHIP_NAME("SiS SiS761GX/SiS966 Mainboard") +}; +#endif diff --git a/src/mainboard/sis/sis761/mptable.c b/src/mainboard/sis/sis761/mptable.c new file mode 100644 index 0000000000..047a187aaa --- /dev/null +++ b/src/mainboard/sis/sis761/mptable.c @@ -0,0 +1,161 @@ +/* + * This file is part of the LinuxBIOS project. + * + * Copyright (C) 2007 AMD + * Written by Yinghai Lu for AMD. + * Copyright (C) 2007 Silicon Integrated Systems Corp. (SiS) + * Written by Morgan Tsai for SiS. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include + +#include +extern unsigned char bus_isa; +extern unsigned char bus_sis966[8]; //1 + +extern unsigned apicid_sis966; + +extern unsigned bus_type[256]; + +void *smp_write_config_table(void *v) +{ + static const char sig[4] = "PCMP"; + static const char oem[8] = "SIS"; + static const char productid[12] = "SiS761GX"; + struct mp_config_table *mc; + unsigned sbdn; + + int i,j; + + mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN); + memset(mc, 0, sizeof(*mc)); + + memcpy(mc->mpc_signature, sig, sizeof(sig)); + mc->mpc_length = sizeof(*mc); /* initially just the header */ + mc->mpc_spec = 0x04; + mc->mpc_checksum = 0; /* not yet computed */ + memcpy(mc->mpc_oem, oem, sizeof(oem)); + memcpy(mc->mpc_productid, productid, sizeof(productid)); + mc->mpc_oemptr = 0; + mc->mpc_oemsize = 0; + mc->mpc_entry_count = 0; /* No entries yet... */ + mc->mpc_lapic = LAPIC_ADDR; + mc->mpe_length = 0; + mc->mpe_checksum = 0; + mc->reserved = 0; + + smp_write_processors(mc); + + get_bus_conf(); + sbdn = sysconf.sbdn; + +/*Bus: Bus ID Type*/ + /* define bus and isa numbers */ + for(j= 0; j < 256 ; j++) { + if(bus_type[j]) + smp_write_bus(mc, j, "PCI "); + } + smp_write_bus(mc, bus_isa, "ISA "); + +/*I/O APICs: APIC ID Version State Address*/ + { + device_t dev; + struct resource *res; + uint32_t dword; + + dev = dev_find_slot(bus_sis966[0], PCI_DEVFN(sbdn+ 0x1,0)); + if (dev) { + res = find_resource(dev, PCI_BASE_ADDRESS_1); + if (res) { + smp_write_ioapic(mc, apicid_sis966, 0x11, res->base); + } + + dword = 0x43c6c643; + pci_write_config32(dev, 0x7c, dword); + + dword = 0x81001a00; + pci_write_config32(dev, 0x80, dword); + + dword = 0xd0001202; + pci_write_config32(dev, 0x84, dword); + + } + } + +/*I/O Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN# +*/ smp_write_intsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x0, apicid_sis966, 0x0); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x1, apicid_sis966, 0x1); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x0, apicid_sis966, 0x2); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x3, apicid_sis966, 0x3); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x4, apicid_sis966, 0x4); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x6, apicid_sis966, 0x6); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x7, apicid_sis966, 0x7); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x8, apicid_sis966, 0x8); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xc, apicid_sis966, 0xc); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xd, apicid_sis966, 0xd); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xe, apicid_sis966, 0xe); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xf, apicid_sis966, 0xf); + + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_sis966[0], ((sbdn+1)<<2)|1, apicid_sis966, 0xa); + + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_sis966[0], ((sbdn+2)<<2)|0, apicid_sis966, 0x16); // 22 + + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_sis966[0], ((sbdn+2)<<2)|1, apicid_sis966, 0x17); // 23 + + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_sis966[0], ((sbdn+6)<<2)|1, apicid_sis966, 0x17); // 23 + + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_sis966[0], ((sbdn+5)<<2)|0, apicid_sis966, 0x14); // 20 + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_sis966[0], ((sbdn+5)<<2)|1, apicid_sis966, 0x17); // 23 + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_sis966[0], ((sbdn+5)<<2)|2, apicid_sis966, 0x15); // 21 + + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_sis966[0], ((sbdn+8)<<2)|0, apicid_sis966, 0x16); // 22 + + for(j=7; j>=2; j--) { + if(!bus_sis966[j]) continue; + for(i=0;i<4;i++) { + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_sis966[j], (0x00<<2)|i, apicid_sis966, 0x10 + (2+j+i+4-sbdn%4)%4); + } + } + + for(j=0; j<2; j++) + for(i=0;i<4;i++) { + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_sis966[1], ((0x06+j)<<2)|i, apicid_sis966, 0x10 + (2+i+j)%4); + } + +/*Local Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN#*/ + smp_write_intsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x0, MP_APIC_ALL, 0x0); + smp_write_intsrc(mc, mp_NMI, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x0, MP_APIC_ALL, 0x1); + /* There is no extension information... */ + + /* Compute the checksums */ + mc->mpe_checksum = smp_compute_checksum(smp_next_mpc_entry(mc), mc->mpe_length); + mc->mpc_checksum = smp_compute_checksum(mc, mc->mpc_length); + printk_debug("Wrote the mp table end at: %p - %p\n", + mc, smp_next_mpe_entry(mc)); + return smp_next_mpe_entry(mc); +} + +unsigned long write_smp_table(unsigned long addr) +{ + void *v; + v = smp_write_floating_table(addr); + return (unsigned long)smp_write_config_table(v); +} diff --git a/src/mainboard/sis/sis761/resourcemap.c b/src/mainboard/sis/sis761/resourcemap.c new file mode 100644 index 0000000000..7e23ad9cc9 --- /dev/null +++ b/src/mainboard/sis/sis761/resourcemap.c @@ -0,0 +1,283 @@ +/* + * This file is part of the LinuxBIOS project. + * + * Copyright (C) 2007 AMD + * Written by Yinghai Lu for AMD. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +static void setup_mb_resource_map(void) +{ + static const unsigned int register_values[] = { + /* Careful set limit registers before base registers which contain the enables */ + /* DRAM Limit i Registers + * F1:0x44 i = 0 + * F1:0x4C i = 1 + * F1:0x54 i = 2 + * F1:0x5C i = 3 + * F1:0x64 i = 4 + * F1:0x6C i = 5 + * F1:0x74 i = 6 + * F1:0x7C i = 7 + * [ 2: 0] Destination Node ID + * 000 = Node 0 + * 001 = Node 1 + * 010 = Node 2 + * 011 = Node 3 + * 100 = Node 4 + * 101 = Node 5 + * 110 = Node 6 + * 111 = Node 7 + * [ 7: 3] Reserved + * [10: 8] Interleave select + * specifies the values of A[14:12] to use with interleave enable. + * [15:11] Reserved + * [31:16] DRAM Limit Address i Bits 39-24 + * This field defines the upper address bits of a 40 bit address + * that define the end of the DRAM region. + */ + PCI_ADDR(0, 0x18, 1, 0x44), 0x0000f8f8, 0x00000000, + PCI_ADDR(0, 0x18, 1, 0x4C), 0x0000f8f8, 0x00000001, + PCI_ADDR(0, 0x18, 1, 0x54), 0x0000f8f8, 0x00000002, + PCI_ADDR(0, 0x18, 1, 0x5C), 0x0000f8f8, 0x00000003, + PCI_ADDR(0, 0x18, 1, 0x64), 0x0000f8f8, 0x00000004, + PCI_ADDR(0, 0x18, 1, 0x6C), 0x0000f8f8, 0x00000005, + PCI_ADDR(0, 0x18, 1, 0x74), 0x0000f8f8, 0x00000006, + PCI_ADDR(0, 0x18, 1, 0x7C), 0x0000f8f8, 0x00000007, + + /* DRAM Base i Registers + * F1:0x40 i = 0 + * F1:0x48 i = 1 + * F1:0x50 i = 2 + * F1:0x58 i = 3 + * F1:0x60 i = 4 + * F1:0x68 i = 5 + * F1:0x70 i = 6 + * F1:0x78 i = 7 + * [ 0: 0] Read Enable + * 0 = Reads Disabled + * 1 = Reads Enabled + * [ 1: 1] Write Enable + * 0 = Writes Disabled + * 1 = Writes Enabled + * [ 7: 2] Reserved + * [10: 8] Interleave Enable + * 000 = No interleave + * 001 = Interleave on A[12] (2 nodes) + * 010 = reserved + * 011 = Interleave on A[12] and A[14] (4 nodes) + * 100 = reserved + * 101 = reserved + * 110 = reserved + * 111 = Interleve on A[12] and A[13] and A[14] (8 nodes) + * [15:11] Reserved + * [13:16] DRAM Base Address i Bits 39-24 + * This field defines the upper address bits of a 40-bit address + * that define the start of the DRAM region. + */ + PCI_ADDR(0, 0x18, 1, 0x40), 0x0000f8fc, 0x00000000, + PCI_ADDR(0, 0x18, 1, 0x48), 0x0000f8fc, 0x00000000, + PCI_ADDR(0, 0x18, 1, 0x50), 0x0000f8fc, 0x00000000, + PCI_ADDR(0, 0x18, 1, 0x58), 0x0000f8fc, 0x00000000, + PCI_ADDR(0, 0x18, 1, 0x60), 0x0000f8fc, 0x00000000, + PCI_ADDR(0, 0x18, 1, 0x68), 0x0000f8fc, 0x00000000, + PCI_ADDR(0, 0x18, 1, 0x70), 0x0000f8fc, 0x00000000, + PCI_ADDR(0, 0x18, 1, 0x78), 0x0000f8fc, 0x00000000, + + /* Memory-Mapped I/O Limit i Registers + * F1:0x84 i = 0 + * F1:0x8C i = 1 + * F1:0x94 i = 2 + * F1:0x9C i = 3 + * F1:0xA4 i = 4 + * F1:0xAC i = 5 + * F1:0xB4 i = 6 + * F1:0xBC i = 7 + * [ 2: 0] Destination Node ID + * 000 = Node 0 + * 001 = Node 1 + * 010 = Node 2 + * 011 = Node 3 + * 100 = Node 4 + * 101 = Node 5 + * 110 = Node 6 + * 111 = Node 7 + * [ 3: 3] Reserved + * [ 5: 4] Destination Link ID + * 00 = Link 0 + * 01 = Link 1 + * 10 = Link 2 + * 11 = Reserved + * [ 6: 6] Reserved + * [ 7: 7] Non-Posted + * 0 = CPU writes may be posted + * 1 = CPU writes must be non-posted + * [31: 8] Memory-Mapped I/O Limit Address i (39-16) + * This field defines the upp adddress bits of a 40-bit address that + * defines the end of a memory-mapped I/O region n + */ + PCI_ADDR(0, 0x18, 1, 0x84), 0x00000048, 0x00000000, + PCI_ADDR(0, 0x18, 1, 0x8C), 0x00000048, 0x00000000, + PCI_ADDR(0, 0x18, 1, 0x94), 0x00000048, 0x00000000, + PCI_ADDR(0, 0x18, 1, 0x9C), 0x00000048, 0x00000000, + PCI_ADDR(0, 0x18, 1, 0xA4), 0x00000048, 0x00000000, + PCI_ADDR(0, 0x18, 1, 0xAC), 0x00000048, 0x00000000, + PCI_ADDR(0, 0x18, 1, 0xB4), 0x00000048, 0x00000000, +// PCI_ADDR(0, 0x18, 1, 0xBC), 0x00000048, 0x00ffff00, + + /* Memory-Mapped I/O Base i Registers + * F1:0x80 i = 0 + * F1:0x88 i = 1 + * F1:0x90 i = 2 + * F1:0x98 i = 3 + * F1:0xA0 i = 4 + * F1:0xA8 i = 5 + * F1:0xB0 i = 6 + * F1:0xB8 i = 7 + * [ 0: 0] Read Enable + * 0 = Reads disabled + * 1 = Reads Enabled + * [ 1: 1] Write Enable + * 0 = Writes disabled + * 1 = Writes Enabled + * [ 2: 2] Cpu Disable + * 0 = Cpu can use this I/O range + * 1 = Cpu requests do not use this I/O range + * [ 3: 3] Lock + * 0 = base/limit registers i are read/write + * 1 = base/limit registers i are read-only + * [ 7: 4] Reserved + * [31: 8] Memory-Mapped I/O Base Address i (39-16) + * This field defines the upper address bits of a 40bit address + * that defines the start of memory-mapped I/O region i + */ + PCI_ADDR(0, 0x18, 1, 0x80), 0x000000f0, 0x00000000, + PCI_ADDR(0, 0x18, 1, 0x88), 0x000000f0, 0x00000000, + PCI_ADDR(0, 0x18, 1, 0x90), 0x000000f0, 0x00000000, + PCI_ADDR(0, 0x18, 1, 0x98), 0x000000f0, 0x00000000, + PCI_ADDR(0, 0x18, 1, 0xA0), 0x000000f0, 0x00000000, + PCI_ADDR(0, 0x18, 1, 0xA8), 0x000000f0, 0x00000000, + PCI_ADDR(0, 0x18, 1, 0xB0), 0x000000f0, 0x00000000, +// PCI_ADDR(0, 0x18, 1, 0xB8), 0x000000f0, 0x00fc0003, + + /* PCI I/O Limit i Registers + * F1:0xC4 i = 0 + * F1:0xCC i = 1 + * F1:0xD4 i = 2 + * F1:0xDC i = 3 + * [ 2: 0] Destination Node ID + * 000 = Node 0 + * 001 = Node 1 + * 010 = Node 2 + * 011 = Node 3 + * 100 = Node 4 + * 101 = Node 5 + * 110 = Node 6 + * 111 = Node 7 + * [ 3: 3] Reserved + * [ 5: 4] Destination Link ID + * 00 = Link 0 + * 01 = Link 1 + * 10 = Link 2 + * 11 = reserved + * [11: 6] Reserved + * [24:12] PCI I/O Limit Address i + * This field defines the end of PCI I/O region n + * [31:25] Reserved + */ +// PCI_ADDR(0, 0x18, 1, 0xC4), 0xFE000FC8, 0x00007000, + PCI_ADDR(0, 0x18, 1, 0xCC), 0xFE000FC8, 0x00000000, + PCI_ADDR(0, 0x18, 1, 0xD4), 0xFE000FC8, 0x00000000, + PCI_ADDR(0, 0x18, 1, 0xDC), 0xFE000FC8, 0x00000000, + + /* PCI I/O Base i Registers + * F1:0xC0 i = 0 + * F1:0xC8 i = 1 + * F1:0xD0 i = 2 + * F1:0xD8 i = 3 + * [ 0: 0] Read Enable + * 0 = Reads Disabled + * 1 = Reads Enabled + * [ 1: 1] Write Enable + * 0 = Writes Disabled + * 1 = Writes Enabled + * [ 3: 2] Reserved + * [ 4: 4] VGA Enable + * 0 = VGA matches Disabled + * 1 = matches all address < 64K and where A[9:0] is in the + * range 3B0-3BB or 3C0-3DF independen of the base & limit registers + * [ 5: 5] ISA Enable + * 0 = ISA matches Disabled + * 1 = Blocks address < 64K and in the last 768 bytes of eack 1K block + * from matching agains this base/limit pair + * [11: 6] Reserved + * [24:12] PCI I/O Base i + * This field defines the start of PCI I/O region n + * [31:25] Reserved + */ +// PCI_ADDR(0, 0x18, 1, 0xC0), 0xFE000FCC, 0x00000033, + PCI_ADDR(0, 0x18, 1, 0xC8), 0xFE000FCC, 0x00000000, + PCI_ADDR(0, 0x18, 1, 0xD0), 0xFE000FCC, 0x00000000, + PCI_ADDR(0, 0x18, 1, 0xD8), 0xFE000FCC, 0x00000000, + + /* Config Base and Limit i Registers + * F1:0xE0 i = 0 + * F1:0xE4 i = 1 + * F1:0xE8 i = 2 + * F1:0xEC i = 3 + * [ 0: 0] Read Enable + * 0 = Reads Disabled + * 1 = Reads Enabled + * [ 1: 1] Write Enable + * 0 = Writes Disabled + * 1 = Writes Enabled + * [ 2: 2] Device Number Compare Enable + * 0 = The ranges are based on bus number + * 1 = The ranges are ranges of devices on bus 0 + * [ 3: 3] Reserved + * [ 6: 4] Destination Node + * 000 = Node 0 + * 001 = Node 1 + * 010 = Node 2 + * 011 = Node 3 + * 100 = Node 4 + * 101 = Node 5 + * 110 = Node 6 + * 111 = Node 7 + * [ 7: 7] Reserved + * [ 9: 8] Destination Link + * 00 = Link 0 + * 01 = Link 1 + * 10 = Link 2 + * 11 - Reserved + * [15:10] Reserved + * [23:16] Bus Number Base i + * This field defines the lowest bus number in configuration region i + * [31:24] Bus Number Limit i + * This field defines the highest bus number in configuration region i + */ +// PCI_ADDR(0, 0x18, 1, 0xE0), 0x0000FC88, 0xff000003, /* link 0 of cpu 0 --> Nvidia MCP55 */ + PCI_ADDR(0, 0x18, 1, 0xE4), 0x0000FC88, 0x00000000, + PCI_ADDR(0, 0x18, 1, 0xE8), 0x0000FC88, 0x00000000, + PCI_ADDR(0, 0x18, 1, 0xEC), 0x0000FC88, 0x00000000, + + }; + + int max; + max = sizeof(register_values)/sizeof(register_values[0]); + setup_resource_map(register_values, max); +} + diff --git a/src/southbridge/sis/sis966/Config.lb b/src/southbridge/sis/sis966/Config.lb new file mode 100644 index 0000000000..565de1aa81 --- /dev/null +++ b/src/southbridge/sis/sis966/Config.lb @@ -0,0 +1,37 @@ +## +## This file is part of the LinuxBIOS project. +## +## Copyright (C) 2007 Silicon Integrated Systems Corp. (SiS) +## Written by Morgan Tsai for SiS. +## +## 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +## + +config chip.h +#driver sis_agp.o +driver sisnb.o +driver sis966.o +driver sis966_usb.o +driver sis966_lpc.o +driver sis966_smbus.o +driver sis966_ide.o +driver sis966_sata.o +driver sis966_usb2.o +driver sis966_aza.o +driver sis966_nic.o +driver sis966_pci.o +driver sis966_pcie.o +driver sis966_ht.o +object sis966_reset.o diff --git a/src/southbridge/sis/sis966/chip.h b/src/southbridge/sis/sis966/chip.h new file mode 100644 index 0000000000..0bda235533 --- /dev/null +++ b/src/southbridge/sis/sis966/chip.h @@ -0,0 +1,39 @@ +/* + * This file is part of the LinuxBIOS project. + * + * Copyright (C) 2007 AMD + * Written by Yinghai Lu for AMD. + * Copyright (C) 2007 Silicon Integrated Systems Corp. (SiS) + * Written by Morgan Tsai for SiS. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef SIS966_CHIP_H +#define SIS966_CHIP_H + +struct southbridge_sis_sis966_config +{ + unsigned int ide0_enable : 1; + unsigned int ide1_enable : 1; + unsigned int sata0_enable : 1; + unsigned int sata1_enable : 1; + unsigned int mac_eeprom_smbus; + unsigned int mac_eeprom_addr; +}; +struct chip_operations; +extern struct chip_operations southbridge_sis_sis966_ops; + +#endif /* SIS966_CHIP_H */ diff --git a/src/southbridge/sis/sis966/id.inc b/src/southbridge/sis/sis966/id.inc new file mode 100644 index 0000000000..5d3a16063f --- /dev/null +++ b/src/southbridge/sis/sis966/id.inc @@ -0,0 +1,36 @@ +/* + * This file is part of the LinuxBIOS project. + * + * Copyright (C) 2007 AMD + * Written by Yinghai Lu for AMD. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + .section ".id", "a", @progbits + + .globl __id_start +__id_start: +vendor: + .asciz MAINBOARD_VENDOR +part: + .asciz MAINBOARD_PART_NUMBER +.long __id_end + 0x80 - vendor /* Reverse offset to the vendor id */ +.long __id_end + 0x80 - part /* Reverse offset to the part number */ +.long PAYLOAD_SIZE + ROM_IMAGE_SIZE /* Size of this romimage */ + .globl __id_end + +__id_end: +.previous diff --git a/src/southbridge/sis/sis966/id.lds b/src/southbridge/sis/sis966/id.lds new file mode 100644 index 0000000000..5fc740fdc2 --- /dev/null +++ b/src/southbridge/sis/sis966/id.lds @@ -0,0 +1,27 @@ +/* + * This file is part of the LinuxBIOS project. + * + * Copyright (C) 2007 AMD + * Written by Yinghai Lu for AMD. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +SECTIONS { + . = (_ROMBASE + ROM_IMAGE_SIZE - 0x80) - (__id_end - __id_start); + .id (.): { + *(.id) + } +} diff --git a/src/southbridge/sis/sis966/romstrap.inc b/src/southbridge/sis/sis966/romstrap.inc new file mode 100644 index 0000000000..e1773b6200 --- /dev/null +++ b/src/southbridge/sis/sis966/romstrap.inc @@ -0,0 +1,78 @@ +/* + * This file is part of the LinuxBIOS project. + * + * Copyright (C) 2004 Tyan Computer + * Written by Yinghai Lu for Tyan Computer. + * Copyright (C) 2007 Silicon Integrated Systems Corp. (SiS) + * Written by Morgan Tsai for SiS. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + .section ".romstrap", "a", @progbits + + + .globl __romstrap_start +__romstrap_start: +rstables: + .long 0x2b16d065 + .long 0x0 + .long 0x0 + .long linkedlist + +linkedlist: + .long 0x0003001C // 10h + .long 0x08000000 // 14h + .long 0x00000000 // 18h + .long 0xFFFFFFFF // 1Ch + + .long 0xFFFFFFFF // 20h + .long 0xFFFFFFFF // 24h + .long 0xFFFFFFFF // 28h + .long 0xFFFFFFFF // 2Ch + +// MAC address -------------------------------- 0x7FFC0h + .long 0x56341200 // 30h, MAC address low 4 byte ---> keep it in 0xffffffc0 + .long 0x00009078 // 34h, MAC address high 4 byte + + .long 0x002309CE // 38h, UUID low 4 byte + .long 0x00E08100 // 3Ch, UUID high 4 byte + + +// Firmware Trap -------------------------------- 0x7FFD0h +/* +//Firmware trap for SiS761+966 + .long 0x00402000 + .long 0x6043A800 + .long 0x00180000 + .long 0x1421C402 +*/ + +//Firmware trap for SiS756+966 ---> keep it in 0xffffffd0 + .long 0x00402000 + .long 0xE043A800 + .long 0x00180000 + .long 0x1421C402 + +rspointers: + .long rstables // It will be 0xffffffe0 + .long rstables + .long rstables + .long rstables + + .globl __romstrap_end + +__romstrap_end: +.previous diff --git a/src/southbridge/sis/sis966/romstrap.lds b/src/southbridge/sis/sis966/romstrap.lds new file mode 100644 index 0000000000..e100570cf2 --- /dev/null +++ b/src/southbridge/sis/sis966/romstrap.lds @@ -0,0 +1,27 @@ +/* + * This file is part of the LinuxBIOS project. + * + * Copyright (C) 2007 AMD + * Written by Yinghai Lu for AMD. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +SECTIONS { + . = (_ROMBASE + ROM_IMAGE_SIZE - 0x10) - (__romstrap_end - __romstrap_start); + .romstrap (.): { + *(.romstrap) + } +} diff --git a/src/southbridge/sis/sis966/sis966.c b/src/southbridge/sis/sis966/sis966.c new file mode 100644 index 0000000000..b2ce896699 --- /dev/null +++ b/src/southbridge/sis/sis966/sis966.c @@ -0,0 +1,253 @@ +/* + * This file is part of the LinuxBIOS project. + * + * Copyright (C) 2004 Tyan Computer + * Written by Yinghai Lu for Tyan Computer. + * Copyright (C) 2006,2007 AMD + * Written by Yinghai Lu for AMD. + * Copyright (C) 2007 Silicon Integrated Systems Corp. (SiS) + * Written by Morgan Tsai for SiS. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include + +#include +#include +#include +#include +#include "sis966.h" + +static uint32_t final_reg; + +static device_t find_lpc_dev( device_t dev, unsigned devfn) +{ + + device_t lpc_dev; + + lpc_dev = dev_find_slot(dev->bus->secondary, devfn); + + if ( !lpc_dev ) return lpc_dev; + +if ((lpc_dev->vendor != PCI_VENDOR_ID_SIS) || ( + (lpc_dev->device != PCI_DEVICE_ID_SIS_SIS966_LPC) + ) ) { + uint32_t id; + id = pci_read_config32(lpc_dev, PCI_VENDOR_ID); + if ( (id < (PCI_VENDOR_ID_SIS | (PCI_DEVICE_ID_SIS_SIS966_LPC << 16))) + ) { + lpc_dev = 0; + } + } + + return lpc_dev; +} + +void sis966_enable(device_t dev) +{ + device_t lpc_dev = 0; + device_t sm_dev = 0; + unsigned index = 0; + unsigned index2 = 0; + uint32_t reg_old, reg; + uint8_t byte; + unsigned deviceid; + unsigned vendorid; + + struct southbridge_sis_sis966_config *conf; + conf = dev->chip_info; + int i; + + unsigned devfn; + + if(dev->device==0x0000) { + vendorid = pci_read_config32(dev, PCI_VENDOR_ID); + deviceid = (vendorid>>16) & 0xffff; +// vendorid &= 0xffff; + } else { +// vendorid = dev->vendor; + deviceid = dev->device; + } + + devfn = (dev->path.u.pci.devfn) & ~7; + switch(deviceid) { + case PCI_DEVICE_ID_SIS_SIS966_HT: + return; + + case PCI_DEVICE_ID_SIS_SIS966_SM2://? + index = 16; + break; + case PCI_DEVICE_ID_SIS_SIS966_USB: + devfn -= (1<<3); + index = 8; + break; + case PCI_DEVICE_ID_SIS_SIS966_EHCI: + devfn -= (1<<3); + index = 20; + break; +/* case PCI_DEVICE_ID_SIS_SIS966_USB3: + devfn -= (1<<3); + index = 20; + break; +*/ + case PCI_DEVICE_ID_SIS_SIS966_NIC1: //two + case PCI_DEVICE_ID_SIS_SIS966_NIC_BRIDGE://two + devfn -= (7<<3); + index = 10; + for(i=0;i<2;i++) { + lpc_dev = find_lpc_dev(dev, devfn - (i<<3)); + if(!lpc_dev) continue; + index -= i; + devfn -= (i<<3); + break; + } + break; + case PCI_DEVICE_ID_SIS_SIS966_AZA: + devfn -= (5<<3); + index = 11; + break; + case PCI_DEVICE_ID_SIS_SIS966_IDE: + devfn -= (3<<3); + index = 14; + break; + case PCI_DEVICE_ID_SIS_SIS966_SATA0: //three + case PCI_DEVICE_ID_SIS_SIS966_SATA1: //three + devfn -= (4<<3); + index = 22; + i = (dev->path.u.pci.devfn) & 7; + if(i>0) { + index -= (i+3); + } + break; + case PCI_DEVICE_ID_SIS_SIS966_PCI: + devfn -= (5<<3); + index = 15; + break; +// case PCI_DEVICE_ID_SIS_SIS966_PCIE_A: +// devfn -= (0x9<<3); // to LPC +// index2 = 9; +// break; + case PCI_DEVICE_ID_SIS_SIS966_PCIE_B_C: //two + devfn -= (0xa<<3); // to LPC + index2 = 8; + for(i=0;i<2;i++) { + lpc_dev = find_lpc_dev(dev, devfn - (i<<3)); + if(!lpc_dev) continue; + index2 -= i; + devfn -= (i<<3); + break; + } + break; + case PCI_DEVICE_ID_SIS_SIS966_PCIE_D: + devfn -= (0xc<<3); // to LPC + index2 = 6; + break; + case PCI_DEVICE_ID_SIS_SIS966_PCIE_E: + devfn -= (0xd<<3); // to LPC + index2 = 5; + break; + case PCI_DEVICE_ID_SIS_SIS966_PCIE_F: + devfn -= (0xe<<3); // to LPC + index2 = 4; + break; + default: + index = 0; + } + + if(!lpc_dev) + lpc_dev = find_lpc_dev(dev, devfn); + + if ( !lpc_dev ) return; + + if(index2!=0) { + sm_dev = dev_find_slot(dev->bus->secondary, devfn + 1); + if(!sm_dev) return; + + if ( sm_dev ) { + reg_old = reg = pci_read_config32(sm_dev, 0xe4); + + if (!dev->enabled) { //disable it + reg |= (1<bus->secondary, devfn + 1); + if(!sm_dev) return; + + final_reg = pci_read_config32(sm_dev, 0xe8); + final_reg &= ~((1<<16)|(1<<8)|(1<<20)|(1<<14)|(1<<22)|(1<<18)|(1<<17)|(1<<15)|(1<<11)|(1<<10)|(1<<9)); + pci_write_config32(sm_dev, 0xe8, final_reg); //enable all at first +#if 0 + reg_old = reg = pci_read_config32(sm_dev, 0xe4); +// reg |= (1<<0); + reg &= ~(0x3f<<4); + if (reg != reg_old) { + printk_debug("sis966.c pcie enabled\n"); + pci_write_config32(sm_dev, 0xe4, reg); + } +#endif + } + + if (!dev->enabled) { + final_reg |= (1 << index);// disable it + //The reason for using final_reg, if diable func 1, the func 2 will be func 1 so We need disable them one time. + } + + if(index == 9 ) { //NIC1 is the final, We need update final reg to 0xe8 + sm_dev = dev_find_slot(dev->bus->secondary, devfn + 1); + if(!sm_dev) return; + reg_old = pci_read_config32(sm_dev, 0xe8); + if (final_reg != reg_old) { + pci_write_config32(sm_dev, 0xe8, final_reg); + } + + } + + +} + +struct chip_operations southbridge_sis_sis966_ops = { + CHIP_NAME("SiS SiS966 Southbridge") + .enable_dev = sis966_enable, +}; diff --git a/src/southbridge/sis/sis966/sis966.h b/src/southbridge/sis/sis966/sis966.h new file mode 100644 index 0000000000..98a6aaaeb9 --- /dev/null +++ b/src/southbridge/sis/sis966/sis966.h @@ -0,0 +1,31 @@ +/* + * This file is part of the LinuxBIOS project. + * + * Copyright (C) 2007 AMD + * Written by Yinghai Lu for AMD. + * Copyright (C) 2007 Silicon Integrated Systems Corp. (SiS) + * Written by Morgan Tsai for SiS. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef SIS966_H +#define SIS966_H + +#include "chip.h" + +void sis966_enable(device_t dev); + +#endif /* SIS966_H */ diff --git a/src/southbridge/sis/sis966/sis966_aza.c b/src/southbridge/sis/sis966/sis966_aza.c new file mode 100644 index 0000000000..48fd0e7288 --- /dev/null +++ b/src/southbridge/sis/sis966/sis966_aza.c @@ -0,0 +1,501 @@ +/* + * This file is part of the LinuxBIOS project. + * + * Copyright (C) 2004 Tyan Computer + * Written by Yinghai Lu for Tyan Computer. + * Copyright (C) 2006,2007 AMD + * Written by Yinghai Lu for AMD. + * Copyright (C) 2007 Silicon Integrated Systems Corp. (SiS) + * Written by Morgan Tsai for SiS. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include +#include "sis966.h" + +uint8_t SiS_SiS7502_init[6][3]={ + +{0x04, 0xFF, 0x07}, +{0x2C, 0xFF, 0x39}, +{0x2D, 0xFF, 0x10}, +{0x2E, 0xFF, 0x91}, +{0x2F, 0xFF, 0x01}, +{0x04, 0xFF, 0x06}, +{0x00, 0x00, 0x00} //End of table +}; + +static int set_bits(uint8_t *port, uint32_t mask, uint32_t val) +{ + uint32_t dword; + int count; + + val &= mask; + dword = readl(port); + dword &= ~mask; + dword |= val; + writel(dword, port); + + count = 50; + do { + dword = readl(port); + dword &= mask; + udelay(100); + } while ((dword != val) && --count); + + if(!count) return -1; + + udelay(540); + return 0; + +} + + uint32_t send_verb(uint8_t *base, uint32_t verb) +{ + + + uint32_t dword; + + dword = readl(base + 0x68); + dword=dword|(unsigned long)0x0002; + writel(dword,base + 0x68); + do { + dword = readl(base + 0x68); + } while ((dword & 1)!=0); + writel(verb, base + 0x60); + udelay(500); + dword = readl(base + 0x68); + dword =(dword |0x1); + writel(dword, base + 0x68); + do { + udelay(120); + dword = readl(base + 0x68); + } while ((dword & 3) != 2); + + dword = readl(base + 0x64); + return dword; + +} + + +#if 1 +static int codec_detect(uint8_t *base) +{ + uint32_t dword; + int idx=0; + + /* 1 */ // controller reset + printk_debug("controller reset\n"); + + set_bits(base + 0x08, 1, 1); + + do{ + dword = readl(base + 0x08)&0x1; + if(idx++>1000) { printk_debug("controller reset fail !!! \n"); break;} + } while (dword !=1); + + dword=send_verb(base,0x000F0000); // get codec VendorId and DeviceId + + if(dword==0) { + printk_debug("No codec!\n"); + return 0; + } + + printk_debug("Codec ID = %lx\n", dword); + +#if 0 + /* 2 */ + dword = readl(base + 0x0e); + dword |= 7; + writel(dword, base + 0x0e); + + /* 3 */ + set_bits(base + 0x08, 1, 0); + + /* 4 */ + set_bits(base + 0x08, 1, 1); + + /* 5 */ + dword = readl(base + 0xe); + dword &= 7; + + /* 6 */ + if(!dword) { + set_bits(base + 0x08, 1, 0); + printk_debug("No codec!\n"); + return 0; + } +#endif + dword=0x1; + return dword; + +} + +#else + +static int codec_detect(uint8_t *base) +{ + uint32_t dword; + + /* 1 */ + set_bits(base + 0x08, 1, 1); + + /* 2 */ + dword = readl(base + 0x0e); + dword |= 7; + writel(dword, base + 0x0e); + + /* 3 */ + set_bits(base + 0x08, 1, 0); + + /* 4 */ + set_bits(base + 0x08, 1, 1); + + /* 5 */ + dword = readl(base + 0xe); + dword &= 7; + + /* 6 */ + if(!dword) { + set_bits(base + 0x08, 1, 0); + printk_debug("No codec!\n"); + return 0; + } + return dword; + +} + +#endif + +#if 1 + +// For SiS demo board PinConfig +static uint32_t verb_data[] = { +#if 0 + 00172083h, + 00172108h, + 001722ECh, + 00172310h, +#endif +//14 + 0x01471c10, + 0x01471d40, + 0x01471e01, + 0x01471f01, +//15 + 0x01571c12, + 0x01571d10, + 0x01571e01, + 0x01571f01, +//16 + 0x01671c11, + 0x01671d60, + 0x01671e01, + 0x01671f01, +//17 + 0x01771c14, + 0x01771d20, + 0x01771e01, + 0x01771f01, +//18 + 0x01871c40, + 0x01871d98, + 0x01871ea1, + 0x01871f01, +//19 + 0x01971c50, + 0x01971d98, + 0x01971ea1, + 0x01971f02, +//1a + 0x01a71c4f, + 0x01a71d30, + 0x01a71e81, + 0x01a71f01, +//1b + 0x01b71c20, + 0x01b71d40, + 0x01b71e01, + 0x01b71f02, +//1c + 0x01c71cf0, + 0x01c71d01, + 0x01c71e33, + 0x01c71f59, +//1d + 0x01d71c01, + 0x01d71de6, + 0x01d71e05, + 0x01d71f40, +//1e + 0x01e71c30, + 0x01e71d11, + 0x01e71e44, + 0x01e71f01, +//1f + 0x01f71c60, + 0x01f71d61, + 0x01f71ec4, + 0x01f71f01, +}; + +#else +// orginal codec pin configuration setting + +static uint32_t verb_data[] = { +#if 0 + 0x00172001, + 0x001721e6, + 0x00172200, + 0x00172300, +#endif + + 0x01471c10, + 0x01471d44, + 0x01471e01, + 0x01471f01, +//1 + 0x01571c12, + 0x01571d14, + 0x01571e01, + 0x01571f01, +//2 + 0x01671c11, + 0x01671d60, + 0x01671e01, + 0x01671f01, +//3 + 0x01771c14, + 0x01771d20, + 0x01771e01, + 0x01771f01, +//4 + 0x01871c30, + 0x01871d9c, + 0x01871ea1, + 0x01871f01, +//5 + 0x01971c40, + 0x01971d9c, + 0x01971ea1, + 0x01971f02, +//6 + 0x01a71c31, + 0x01a71d34, + 0x01a71e81, + 0x01a71f01, +//7 + 0x01b71c1f, + 0x01b71d44, + 0x01b71e21, + 0x01b71f02, +//8 + 0x01c71cf0, + 0x01c71d11, + 0x01c71e11, + 0x01c71f41, +//9 + 0x01d71c3e, + 0x01d71d01, + 0x01d71e83, + 0x01d71f99, +//10 + 0x01e71c20, + 0x01e71d41, + 0x01e71e45, + 0x01e71f01, +//11 + 0x01f71c50, + 0x01f71d91, + 0x01f71ec5, + 0x01f71f01, +}; + +#endif +static unsigned find_verb(uint32_t viddid, uint32_t **verb) +{ + if((viddid == 0x10ec0883) || (viddid == 0x10ec0882) || (viddid == 0x10ec0880)) return 0; + *verb = (uint32_t *)verb_data; + return sizeof(verb_data)/sizeof(uint32_t); +} + + +static void codec_init(uint8_t *base, int addr) +{ + uint32_t dword; + uint32_t *verb; + unsigned verb_size; + int i; + + /* 1 */ + do { + dword = readl(base + 0x68); + } while (dword & 1); + + dword = (addr<<28) | 0x000f0000; + writel(dword, base + 0x60); + + do { + dword = readl(base + 0x68); + } while ((dword & 3)!=2); + + dword = readl(base + 0x64); + + /* 2 */ + printk_debug("codec viddid: %08x\n", dword); + verb_size = find_verb(dword, &verb); + + if(!verb_size) { + printk_debug("No verb!\n"); + return; + } + + printk_debug("verb_size: %d\n", verb_size); + /* 3 */ + for(i=0; i=0; i--) { + if( codec_mask & (1<base; + printk_debug("base = %08x\n", base); + + codec_mask = codec_detect(base); + + if(codec_mask) { + printk_debug("codec_mask = %02x\n", codec_mask); + codecs_init(base, codec_mask); + } + +#if 0 +{ + int i; + printk_debug("Azalia PCI config \n"); + for(i=0;i<0xFF;i+=4) + { + if((i%16)==0) + { + print_debug("\r\n");print_debug_hex8(i);print_debug(" "); + } + outl(0x80000800+i,0xcf8); + print_debug_hex32(inl(0xcfc)); + print_debug(" "); + } + print_debug("\r\n"); +} +#endif + +} + +static void lpci_set_subsystem(device_t dev, unsigned vendor, unsigned device) +{ + pci_write_config32(dev, 0x40, + ((device & 0xffff) << 16) | (vendor & 0xffff)); +} + +static struct pci_operations lops_pci = { + .set_subsystem = lpci_set_subsystem, +}; + +static struct device_operations aza_audio_ops = { + .read_resources = pci_dev_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_dev_enable_resources, +// .enable = sis966_enable, + .init = aza_init, + .scan_bus = 0, + .ops_pci = &lops_pci, +}; + +static struct pci_driver azaaudio_driver __pci_driver = { + .ops = &aza_audio_ops, + .vendor = PCI_VENDOR_ID_SIS, + .device = PCI_DEVICE_ID_SIS_SIS966_AZA, +}; + diff --git a/src/southbridge/sis/sis966/sis966_early_ctrl.c b/src/southbridge/sis/sis966/sis966_early_ctrl.c new file mode 100644 index 0000000000..3d6abc7561 --- /dev/null +++ b/src/southbridge/sis/sis966/sis966_early_ctrl.c @@ -0,0 +1,60 @@ +/* + * This file is part of the LinuxBIOS project. + * + * Copyright (C) 2007 AMD + * Written by Yinghai Lu for AMD. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +static unsigned get_sbdn(unsigned bus) +{ + device_t dev; + + /* Find the device. + */ + dev = pci_locate_device_on_bus( + PCI_ID(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_SIS_SIS966_HT), + bus); + + return (dev>>15) & 0x1f; + +} + +static void hard_reset(void) +{ + set_bios_reset(); + + /* full reset */ + outb(0x0a, 0x0cf9); + outb(0x0e, 0x0cf9); +} +static void enable_fid_change_on_sb(unsigned sbbusn, unsigned sbdn) +{ +/* default value for sis966 is good */ + /* set VFSMAF ( VID/FID System Management Action Field) to 2 */ + +} + +static void soft_reset(void) +{ + set_bios_reset(); +#if 1 + /* link reset */ + outb(0x02, 0x0cf9); + outb(0x06, 0x0cf9); +#endif +} + diff --git a/src/southbridge/sis/sis966/sis966_early_setup_car.c b/src/southbridge/sis/sis966/sis966_early_setup_car.c new file mode 100644 index 0000000000..370951a2d5 --- /dev/null +++ b/src/southbridge/sis/sis966/sis966_early_setup_car.c @@ -0,0 +1,429 @@ +/* + * This file is part of the LinuxBIOS project. + * + * Copyright (C) 2006 AMD + * Written by Yinghai Lu for AMD. + * Copyright (C) 2007 Silicon Integrated Systems Corp. (SiS) + * Written by Morgan Tsai for SiS. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +static int set_ht_link_sis966(uint8_t ht_c_num) +{ + unsigned vendorid = 0x10de; + unsigned val = 0x01610109; + /* Nvidia sis966 hardcode, hw can not set it automatically */ + return set_ht_link_buffer_counts_chain(ht_c_num, vendorid, val); +} + +static void setup_ss_table(unsigned index, unsigned where, unsigned control, const unsigned int *register_values, int max) +{ + int i; + + unsigned val; + + val = inl(control); + val &= 0xfffffffe; + outl(val, control); + + outl(0, index); //index + for(i = 0; i < max; i++) { + unsigned long reg; + reg = register_values[i]; + outl(reg, where); + } + + val = inl(control); + val |= 1; + outl(val, control); + +} + +/* SIZE 0x100 */ +#define ANACTRL_IO_BASE 0x2800 +#define ANACTRL_REG_POS 0x68 + +/* SIZE 0x100 */ +#define SYSCTRL_IO_BASE 0x2400 +#define SYSCTRL_REG_POS 0x64 + +/* SIZE 0x100 */ +#define ACPICTRL_IO_BASE 0x2000 +#define ACPICTRL_REG_POS 0x60 + +/* + 16 1 1 1 1 8 :0 + 16 0 4 0 0 8 :1 + 16 0 4 2 2 4 :2 + 4 4 4 4 4 8 :3 + 8 8 4 0 0 8 :4 + 8 0 4 4 4 8 :5 +*/ + +#ifndef SIS966_PCI_E_X_0 + #define SIS966_PCI_E_X_0 4 +#endif +#ifndef SIS966_PCI_E_X_1 + #define SIS966_PCI_E_X_1 4 +#endif +#ifndef SIS966_PCI_E_X_2 + #define SIS966_PCI_E_X_2 4 +#endif +#ifndef SIS966_PCI_E_X_3 + #define SIS966_PCI_E_X_3 4 +#endif + +#ifndef SIS966_USE_NIC + #define SIS966_USE_NIC 0 +#endif + +#ifndef SIS966_USE_AZA + #define SIS966_USE_AZA 0 +#endif + +#define SIS966_CHIP_REV 3 + +static void sis966_early_set_port(unsigned sis966_num, unsigned *busn, unsigned *devn, unsigned *io_base) +{ + + static const unsigned int ctrl_devport_conf[] = { + PCI_ADDR(0, 1, 1, ANACTRL_REG_POS), ~(0x0000ff00), ANACTRL_IO_BASE, + PCI_ADDR(0, 1, 1, SYSCTRL_REG_POS), ~(0x0000ff00), SYSCTRL_IO_BASE, + PCI_ADDR(0, 1, 1, ACPICTRL_REG_POS), ~(0x0000ff00), ACPICTRL_IO_BASE, + }; + + int j; + for(j = 0; j < sis966_num; j++ ) { + setup_resource_map_offset(ctrl_devport_conf, + sizeof(ctrl_devport_conf)/sizeof(ctrl_devport_conf[0]), + PCI_DEV(busn[j], devn[j], 0) , io_base[j]); + } +} + +static void sis966_early_clear_port(unsigned sis966_num, unsigned *busn, unsigned *devn, unsigned *io_base) +{ + + static const unsigned int ctrl_devport_conf_clear[] = { + PCI_ADDR(0, 1, 1, ANACTRL_REG_POS), ~(0x0000ff00), 0, + PCI_ADDR(0, 1, 1, SYSCTRL_REG_POS), ~(0x0000ff00), 0, + PCI_ADDR(0, 1, 1, ACPICTRL_REG_POS), ~(0x0000ff00), 0, + }; + + int j; + for(j = 0; j < sis966_num; j++ ) { + setup_resource_map_offset(ctrl_devport_conf_clear, + sizeof(ctrl_devport_conf_clear)/sizeof(ctrl_devport_conf_clear[0]), + PCI_DEV(busn[j], devn[j], 0) , io_base[j]); + } + + +} +static void delayx(uint8_t value) { +#if 1 + int i; + for(i=0;i<0x8000;i++) { + outb(value, 0x80); + } +#endif +} + +static void sis966_early_pcie_setup(unsigned busnx, unsigned devnx, unsigned anactrl_io_base, unsigned pci_e_x) +{ + uint32_t tgio_ctrl; + uint32_t pll_ctrl; + uint32_t dword; + int i; + device_t dev; + dev = PCI_DEV(busnx, devnx+1, 1); + dword = pci_read_config32(dev, 0xe4); + dword |= 0x3f0; // disable it at first + pci_write_config32(dev, 0xe4, dword); + + for(i=0; i<3; i++) { + tgio_ctrl = inl(anactrl_io_base + 0xcc); + tgio_ctrl &= ~(3<<9); + tgio_ctrl |= (i<<9); + outl(tgio_ctrl, anactrl_io_base + 0xcc); + pll_ctrl = inl(anactrl_io_base + 0x30); + pll_ctrl |= (1<<31); + outl(pll_ctrl, anactrl_io_base + 0x30); + do { + pll_ctrl = inl(anactrl_io_base + 0x30); + } while (!(pll_ctrl & 1)); + } + tgio_ctrl = inl(anactrl_io_base + 0xcc); + tgio_ctrl &= ~((7<<4)|(1<<8)); + tgio_ctrl |= (pci_e_x<<4)|(1<<8); + outl(tgio_ctrl, anactrl_io_base + 0xcc); + +// wait 100us + delayx(1); + + dword = pci_read_config32(dev, 0xe4); + dword &= ~(0x3f0); // enable + pci_write_config32(dev, 0xe4, dword); + +// need to wait 100ms + delayx(1000); +} + +static void sis966_early_setup(unsigned sis966_num, unsigned *busn, unsigned *devn, unsigned *io_base, unsigned *pci_e_x) +{ + + static const unsigned int ctrl_conf_1[] = { + RES_PORT_IO_32, ACPICTRL_IO_BASE + 0x10, 0x0007ffff, 0xff78000, + RES_PORT_IO_32, ACPICTRL_IO_BASE + 0xa4, 0xffedffff, 0x0012000, + RES_PORT_IO_32, ACPICTRL_IO_BASE + 0xac, 0xfffffdff, 0x0000200, + RES_PORT_IO_32, ACPICTRL_IO_BASE + 0xb4, 0xfffffffd, 0x0000002, + + RES_PORT_IO_32, ANACTRL_IO_BASE + 0x24, 0xc0f0f08f, 0x26020230, + RES_PORT_IO_32, ANACTRL_IO_BASE + 0x34, 0x00000000, 0x22222222, + RES_PORT_IO_32, ANACTRL_IO_BASE + 0x08, 0x7FFFFFFF, 0x00000000, + RES_PORT_IO_32, ANACTRL_IO_BASE + 0x2C, 0x7FFFFFFF, 0x80000000, + RES_PORT_IO_32, ANACTRL_IO_BASE + 0xCC, 0xFFFFF9FF, 0x00000000, + RES_PORT_IO_32, ANACTRL_IO_BASE + 0x30, 0x8FFFFFFF, 0x40000000, + RES_PORT_IO_32, ANACTRL_IO_BASE + 0xCC, 0xFFFFF9FF, 0x00000200, + RES_PORT_IO_32, ANACTRL_IO_BASE + 0x30, 0x8FFFFFFF, 0x40000000, + RES_PORT_IO_32, ANACTRL_IO_BASE + 0xCC, 0xFFFFF9FF, 0x00000400, + RES_PORT_IO_32, ANACTRL_IO_BASE + 0x30, 0x8FFFFFFF, 0x40000000, + RES_PORT_IO_32, ANACTRL_IO_BASE + 0x74, 0xFFFF0FF5, 0x0000F000, + RES_PORT_IO_32, ANACTRL_IO_BASE + 0x78, 0xFF00FF00, 0x00100010, + RES_PORT_IO_32, ANACTRL_IO_BASE + 0x7C, 0xFF0FF0FF, 0x00500500, + RES_PORT_IO_32, ANACTRL_IO_BASE + 0x80, 0xFFFFFFE7, 0x00000000, + RES_PORT_IO_32, ANACTRL_IO_BASE + 0x60, 0xFFCFFFFF, 0x00300000, + RES_PORT_IO_32, ANACTRL_IO_BASE + 0x90, 0xFFFF00FF, 0x0000FF00, + RES_PORT_IO_32, ANACTRL_IO_BASE + 0x9C, 0xFF00FFFF, 0x00070000, + + RES_PCI_IO, PCI_ADDR(0, 0, 0, 0x40), 0x00000000, 0xCB8410DE, + RES_PCI_IO, PCI_ADDR(0, 0, 0, 0x48), 0xFFFFDCED, 0x00002002, + RES_PCI_IO, PCI_ADDR(0, 0, 0, 0x78), 0xFFFFFF8E, 0x00000011, + RES_PCI_IO, PCI_ADDR(0, 0, 0, 0x80), 0xFFFF0000, 0x00009923, + RES_PCI_IO, PCI_ADDR(0, 0, 0, 0x88), 0xFFFFFFFE, 0x00000000, + RES_PCI_IO, PCI_ADDR(0, 0, 0, 0x8C), 0xFFFF0000, 0x0000007F, + RES_PCI_IO, PCI_ADDR(0, 0, 0, 0xDC), 0xFFFEFFFF, 0x00010000, + + RES_PCI_IO, PCI_ADDR(0, 1, 0, 0x40), 0x00000000, 0xCB8410DE, + RES_PCI_IO, PCI_ADDR(0, 1, 0, 0x74), 0xFFFFFF7B, 0x00000084, + RES_PCI_IO, PCI_ADDR(0, 1, 0, 0xF8), 0xFFFFFFCF, 0x00000010, + + RES_PCI_IO, PCI_ADDR(0, 1, 1, 0xC4), 0xFFFFFFFE, 0x00000001, + RES_PCI_IO, PCI_ADDR(0, 1, 1, 0xF0), 0x7FFFFFFD, 0x00000002, + RES_PCI_IO, PCI_ADDR(0, 1, 1, 0xF8), 0xFFFFFFCF, 0x00000010, + + RES_PCI_IO, PCI_ADDR(0, 8, 0, 0x40), 0x00000000, 0xCB8410DE, + RES_PCI_IO, PCI_ADDR(0, 8, 0, 0x68), 0xFFFFFF00, 0x000000FF, + RES_PCI_IO, PCI_ADDR(0, 8, 0, 0xF8), 0xFFFFFFBF, 0x00000040,//Enable bridge mode + + RES_PCI_IO, PCI_ADDR(0, 9, 0, 0x40), 0x00000000, 0xCB8410DE, + RES_PCI_IO, PCI_ADDR(0, 9, 0, 0x68), 0xFFFFFF00, 0x000000FF, + RES_PCI_IO, PCI_ADDR(0, 9, 0, 0xF8), 0xFFFFFFBF, 0x00000040,//Enable bridge mode + }; + + static const unsigned int ctrl_conf_1_1[] = { + RES_PCI_IO, PCI_ADDR(0, 5, 0, 0x40), 0x00000000, 0xCB8410DE, + RES_PCI_IO, PCI_ADDR(0, 5, 0, 0x50), 0xFFFFFFFC, 0x00000003, + RES_PCI_IO, PCI_ADDR(0, 5, 0, 0x64), 0xFFFFFFFE, 0x00000001, + RES_PCI_IO, PCI_ADDR(0, 5, 0, 0x70), 0xFFF0FFFF, 0x00040000, + RES_PCI_IO, PCI_ADDR(0, 5, 0, 0xAC), 0xFFFFF0FF, 0x00000100, + RES_PCI_IO, PCI_ADDR(0, 5, 0, 0x7C), 0xFFFFFFEF, 0x00000000, + RES_PCI_IO, PCI_ADDR(0, 5, 0, 0xC8), 0xFF00FF00, 0x000A000A, + RES_PCI_IO, PCI_ADDR(0, 5, 0, 0xD0), 0xF0FFFFFF, 0x03000000, + RES_PCI_IO, PCI_ADDR(0, 5, 0, 0xE0), 0xF0FFFFFF, 0x03000000, + }; + + + static const unsigned int ctrl_conf_sis966_only[] = { + RES_PCI_IO, PCI_ADDR(0, 1, 1, 0x40), 0x00000000, 0xCB8410DE, + RES_PCI_IO, PCI_ADDR(0, 1, 1, 0xE0), 0xFFFFFEFF, 0x00000000, + RES_PCI_IO, PCI_ADDR(0, 1, 1, 0xE4), 0xFFFFFFFB, 0x00000000, + RES_PCI_IO, PCI_ADDR(0, 1, 1, 0xE8), 0xFFA9C8FF, 0x00003000, + +// RES_PCI_IO, PCI_ADDR(0, 4, 0, 0x40), 0x00000000, 0xCB8410DE, +// RES_PCI_IO, PCI_ADDR(0, 4, 0, 0xF8), 0xFFFFFFCF, 0x00000010, + + RES_PCI_IO, PCI_ADDR(0, 2, 0, 0x40), 0x00000000, 0xCB8410DE, + + RES_PCI_IO, PCI_ADDR(0, 2, 1, 0x40), 0x00000000, 0xCB8410DE, + RES_PCI_IO, PCI_ADDR(0, 2, 1, 0x64), 0xF87FFFFF, 0x05000000, + RES_PCI_IO, PCI_ADDR(0, 2, 1, 0x78), 0xFFC07FFF, 0x00360000, + RES_PCI_IO, PCI_ADDR(0, 2, 1, 0x68), 0xFE00D03F, 0x013F2C00, + RES_PCI_IO, PCI_ADDR(0, 2, 1, 0x70), 0xFFF7FFFF, 0x00080000, + RES_PCI_IO, PCI_ADDR(0, 2, 1, 0x7C), 0xFFFFF00F, 0x00000570, + RES_PCI_IO, PCI_ADDR(0, 2, 1, 0xF8), 0xFFFFFFCF, 0x00000010, + + RES_PCI_IO, PCI_ADDR(0, 6, 0, 0x04), 0xFFFFFEFB, 0x00000104, + RES_PCI_IO, PCI_ADDR(0, 6, 0, 0x3C), 0xF5FFFFFF, 0x0A000000, + RES_PCI_IO, PCI_ADDR(0, 6, 0, 0x40), 0x00C8FFFF, 0x07330000, + RES_PCI_IO, PCI_ADDR(0, 6, 0, 0x48), 0xFFFFFFF8, 0x00000005, + RES_PCI_IO, PCI_ADDR(0, 6, 0, 0x4C), 0xFE02FFFF, 0x004C0000, + RES_PCI_IO, PCI_ADDR(0, 6, 0, 0x74), 0xFFFFFFC0, 0x00000000, + RES_PCI_IO, PCI_ADDR(0, 6, 0, 0xC0), 0x00000000, 0xCB8410DE, + RES_PCI_IO, PCI_ADDR(0, 6, 0, 0xC4), 0xFFFFFFF8, 0x00000007, + +#if SIS966_USE_AZA == 1 + RES_PCI_IO, PCI_ADDR(0, 6, 1, 0x40), 0x00000000, 0xCB8410DE, + +// RES_PCI_IO, PCI_ADDR(0, 1, 1, 0xE4), ~(1<<14), 1<<14, +#endif +// play a while with GPIO in SIS966 +#ifdef SIS966_MB_SETUP + SIS966_MB_SETUP +#endif + +#if SIS966_USE_AZA == 1 + RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0+ 21, ~(3<<2), (2<<2), + RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0+ 22, ~(3<<2), (2<<2), + RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0+ 46, ~(3<<2), (2<<2), +#endif + + + }; + + static const unsigned int ctrl_conf_master_only[] = { + + RES_PORT_IO_32, ACPICTRL_IO_BASE + 0x80, 0xEFFFFFF, 0x01000000, + + RES_PCI_IO, PCI_ADDR(0, 1, 0, 0x78), 0xC0FFFFFF, 0x19000000, + + //Master SIS966 ????YHLU + RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0+ 0, ~(3<<2), (0<<2), + + }; + + static const unsigned int ctrl_conf_2[] = { + /* I didn't put pcie related stuff here */ + + RES_PCI_IO, PCI_ADDR(0, 0, 0, 0x74), 0xFFFFF00F, 0x000009D0, + RES_PCI_IO, PCI_ADDR(0, 1, 0, 0x74), 0xFFFF7FFF, 0x00008000, + + RES_PORT_IO_32, SYSCTRL_IO_BASE + 0x48, 0xFFFEFFFF, 0x00010000, + + RES_PORT_IO_32, ANACTRL_IO_BASE + 0x60, 0xFFFFFF00, 0x00000012, + + +#if SIS966_USE_NIC == 1 + RES_PCI_IO, PCI_ADDR(0, 1, 1, 0xe4), ~((1<<22)|(1<<20)), (1<<22)|(1<<20), + + RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0+ 4, ~(0xff), ((0<<4)|(1<<2)|(0<<0)), + RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0+ 4, ~(0xff), ((0<<4)|(1<<2)|(1<<0)), +#endif + + }; + + + int j, i; + + for(j=0; j1) ) { + setup_resource_map_x_offset(ctrl_conf_master_only, sizeof(ctrl_conf_master_only)/sizeof(ctrl_conf_master_only[0]), + PCI_DEV(busn[j], devn[j], 0), io_base[j]); + } + + setup_resource_map_x_offset(ctrl_conf_2, sizeof(ctrl_conf_2)/sizeof(ctrl_conf_2[0]), + PCI_DEV(busn[j], devn[j], 0), io_base[j]); + + } + +#if 0 + for(j=0; j< sis966_num; j++) { + // PCI-E (XSPLL) SS table 0x40, x044, 0x48 + // SATA (SPPLL) SS table 0xb0, 0xb4, 0xb8 + // CPU (PPLL) SS table 0xc0, 0xc4, 0xc8 + setup_ss_table(io_base[j] + ANACTRL_IO_BASE+0x40, io_base[j] + ANACTRL_IO_BASE+0x44, + io_base[j] + ANACTRL_IO_BASE+0x48, pcie_ss_tbl, 64); + setup_ss_table(io_base[j] + ANACTRL_IO_BASE+0xb0, io_base[j] + ANACTRL_IO_BASE+0xb4, + io_base[j] + ANACTRL_IO_BASE+0xb8, sata_ss_tbl, 64); + setup_ss_table(io_base[j] + ANACTRL_IO_BASE+0xc0, io_base[j] + ANACTRL_IO_BASE+0xc4, + io_base[j] + ANACTRL_IO_BASE+0xc8, cpu_ss_tbl, 64); + } +#endif + +} + +#ifndef HT_CHAIN_NUM_MAX + +#define HT_CHAIN_NUM_MAX 4 +#define HT_CHAIN_BUSN_D 0x40 +#define HT_CHAIN_IOBASE_D 0x4000 + +#endif + +static int sis966_early_setup_x(void) +{ + /*find out how many sis966 we have */ + unsigned busn[HT_CHAIN_NUM_MAX]; + unsigned devn[HT_CHAIN_NUM_MAX]; + unsigned io_base[HT_CHAIN_NUM_MAX]; + /* + FIXME: May have problem if there is different SIS966 HTX card with different PCI_E lane allocation + Need to use same trick about pci1234 to verify node/link connection + */ + unsigned pci_e_x[HT_CHAIN_NUM_MAX] = {SIS966_PCI_E_X_0, SIS966_PCI_E_X_1, SIS966_PCI_E_X_2, SIS966_PCI_E_X_3 }; + int sis966_num = 0; + unsigned busnx; + unsigned devnx; + int ht_c_index,j; + + /* FIXME: multi pci segment handling */ + + /* Any system that only have IO55 without SIS966? */ + for(ht_c_index = 0; ht_c_index for Tyan Computer. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +static const unsigned int pcie_ss_tbl[] = { + 0x0C504103f, + 0x0C504103f, + 0x0C504103f, + 0x0C5042040, + 0x0C5042040, + 0x0C5042040, + 0x0C5043041, + 0x0C5043041, + 0x0C5043041, + 0x0C5043041, + 0x0C5044042, + 0x0C5044042, + 0x0C5044042, + 0x0C5045043, + 0x0C5045043, + 0x0C5045043, + 0x0C5045043, + 0x0C5045043, + 0x0C5046044, + 0x0C5046044, + 0x0C5046044, + 0x0C5046044, + 0x0C5047045, + 0x0C5047045, + 0x0C5047045, + 0x0C5047045, + 0x0C5047045, + 0x0C5048046, + 0x0C5048046, + 0x0C5048046, + 0x0C5048046, + 0x0C5049047, + 0x0C5049047, + 0x0C5049047, + 0x0C504a048, + 0x0C504a048, + 0x0C504b049, + 0x0C504b049, + 0x0C504a048, + 0x0C504a048, + 0x0C5049047, + 0x0C5049047, + 0x0C5048046, + 0x0C5048046, + 0x0C5048046, + 0x0C5047045, + 0x0C5047045, + 0x0C5047045, + 0x0C5047045, + 0x0C5047045, + 0x0C5046044, + 0x0C5046044, + 0x0C5046044, + 0x0C5046044, + 0x0C5045043, + 0x0C5045043, + 0x0C5045043, + 0x0C5044042, + 0x0C5044042, + 0x0C5044042, + 0x0C5043041, + 0x0C5043041, + 0x0C5042040, + 0x0C5042040, +}; +static const unsigned int sata_ss_tbl[] = { + 0x0c9044042, + 0x0c9044042, + 0x0c9044042, + 0x0c9045043, + 0x0c9045043, + 0x0c9045043, + 0x0c9045043, + 0x0c9045043, + 0x0c9046044, + 0x0c9046044, + 0x0c9046044, + 0x0c9046044, + 0x0c9047045, + 0x0c9047045, + 0x0c9047045, + 0x0c9047045, + 0x0c9047045, + 0x0c9048046, + 0x0c9048046, + 0x0c9048046, + 0x0c9048046, + 0x0c9049047, + 0x0c9049047, + 0x0c9049047, + 0x0c9049047, + 0x0c904a048, + 0x0c904a048, + 0x0c904a048, + 0x0c904a048, + 0x0c904b049, + 0x0c904b049, + 0x0c904b049, + 0x0c904b049, + 0x0c904b049, + 0x0c904b049, + 0x0c904a048, + 0x0c904a048, + 0x0c904a048, + 0x0c904a048, + 0x0c9049047, + 0x0c9049047, + 0x0c9049047, + 0x0c9049047, + 0x0c9048046, + 0x0c9048046, + 0x0c9048046, + 0x0c9048046, + 0x0c9047045, + 0x0c9047045, + 0x0c9047045, + 0x0c9047045, + 0x0c9047045, + 0x0c9046044, + 0x0c9046044, + 0x0c9046044, + 0x0c9046044, + 0x0c9045043, + 0x0c9045043, + 0x0c9045043, + 0x0c9045043, + 0x0c9045043, + 0x0c9044042, + 0x0c9044042, + 0x0c9044042, +}; + +static const unsigned int cpu_ss_tbl[] = { + 0x0C5038036, + 0x0C5038036, + 0x0C5038036, + 0x0C5037035, + 0x0C5037035, + 0x0C5037035, + 0x0C5037035, + 0x0C5036034, + 0x0C5036034, + 0x0C5036034, + 0x0C5036034, + 0x0C5036034, + 0x0C5035033, + 0x0C5035033, + 0x0C5035033, + 0x0C5035033, + 0x0C5035033, + 0x0C5035033, + 0x0C5034032, + 0x0C5034032, + 0x0C5034032, + 0x0C5034032, + 0x0C5034032, + 0x0C5034032, + 0x0C5035033, + 0x0C5035033, + 0x0C5035033, + 0x0C5035033, + 0x0C5035033, + 0x0C5036034, + 0x0C5036034, + 0x0C5036034, + 0x0C5036034, + 0x0C5036034, + 0x0C5037035, + 0x0C5037035, + 0x0C5037035, + 0x0C5037035, + 0x0C5038036, + 0x0C5038036, + 0x0C5038036, + 0x0C5038036, + 0x0C5039037, + 0x0C5039037, + 0x0C5039037, + 0x0C5039037, + 0x0C503a038, + 0x0C503a038, + 0x0C503a038, + 0x0C503a038, + 0x0C503b039, + 0x0C503b039, + 0x0C503b039, + 0x0C503b039, + 0x0C503b039, + 0x0C503a038, + 0x0C503a038, + 0x0C503a038, + 0x0C503a038, + 0x0C503a038, + 0x0C5039037, + 0x0C5039037, + 0x0C5039037, + 0x0C5039037, +}; + + diff --git a/src/southbridge/sis/sis966/sis966_early_smbus.c b/src/southbridge/sis/sis966/sis966_early_smbus.c new file mode 100644 index 0000000000..6244025941 --- /dev/null +++ b/src/southbridge/sis/sis966/sis966_early_smbus.c @@ -0,0 +1,904 @@ +/* + * This file is part of the LinuxBIOS project. + * + * Copyright (C) 2007 Silicon Integrated Systems Corp. (SiS) + * Written by Morgan Tsai for SiS. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "sis966_smbus.h" + +#define SMBUS0_IO_BASE 0x8D0 + +uint8_t SiS_LPC_init[33][3]={ +{0x04, 0xF8, 0x07}, //Reg 0x04 +{0x45, 0x00, 0x00}, //Reg 0x45 //Enable Rom Flash +{0x46, 0x00, 0x3D}, //Reg 0x46 +{0x47, 0x00, 0xDD}, //Reg 0x47 +{0x48, 0x00, 0x12}, //Reg 0x48 +{0x64, 0x00, 0xFF}, //Reg 0x64 +{0x65, 0x00, 0xC1}, //Reg 0x65 +{0x68, 0x00, 0x89}, //Reg 0x68 //SB.ASM, START POST +{0x69, 0x00, 0x80}, //Reg 0x69 +{0x6B, 0x00, 0x00}, //Reg 0x6B //SBBB.ASM +{0x6C, 0xFF, 0x97}, //Reg 0x6C //SBBB.ASM +{0x6E, 0x00, 0x00}, //Reg 0x6E //SBBB.ASM But in Early Post sets 0x04. +{0x6F, 0xFF, 0x14}, //Reg 0x6F //SBBB.ASM +{0x77, 0x00, 0x0E}, //Reg 0x77 //SBOEM.ASM, EARLY POST +{0x78, 0x00, 0x20}, //Reg 0x78 +{0x7B, 0x00, 0x88}, //Reg 0x7B +{0x7F, 0x00, 0x40}, //Reg 0x7F //SBOEM.ASM, EARLY POST +{0xC1, 0x00, 0xF0}, //Reg 0xC1 +{0xC2, 0x00, 0x01}, //Reg 0xC2 +{0xC3, 0x00, 0x00}, //Reg 0xC3 //NBAGPBB.ASM +{0xC9, 0x00, 0x80}, //Reg 0xC9 +{0xCF, 0x00, 0x45}, //Reg 0xCF +{0xD0, 0x00, 0x02}, //Reg 0xD0 +{0xD4, 0x00, 0x44}, //Reg 0xD4 +{0xD5, 0x00, 0x62}, //Reg 0xD5 +{0xD6, 0x00, 0x32}, //Reg 0xD6 +{0xD8, 0x00, 0x45}, //Reg 0xD8 +{0xDA, 0x00, 0xDA}, //Reg 0xDA +{0xDB, 0x00, 0x61}, //Reg 0xDB +{0xDC, 0x00, 0xAA}, //Reg 0xDC +{0xDD, 0x00, 0xAA}, //Reg 0xDD +{0xDE, 0x00, 0xAA}, //Reg 0xDE +{0xDF, 0x00, 0xAA}, //Reg 0xDF +{0x00, 0x00, 0x00} //End of table +}; +uint8_t SiS_NBPCIE_init[43][3]={ +{0x3D, 0x00, 0x00}, //Reg 0x3D +{0x1C, 0xFE, 0x01}, //Reg 0x1C +{0x1D, 0xFE, 0x01}, //Reg 0x1D +{0x24, 0xFE, 0x01}, //Reg 0x24 +{0x26, 0xFE, 0x01}, //Reg 0x26 +{0x40, 0xFF, 0x10}, //Reg 0x40 +{0x43, 0xFF, 0x78}, //Reg 0x43 +{0x44, 0xFF, 0x02}, //Reg 0x44 +{0x45, 0xFF, 0x10}, //Reg 0x45 +{0x48, 0xFF, 0x52}, //Reg 0x48 +{0x49, 0xFF, 0xE3}, //Reg 0x49 +{0x5A, 0x00, 0x00}, //Reg 0x4A +{0x4B, 0x00, 0x16}, //Reg 0x4B +{0x4C, 0x00, 0x80}, //Reg 0x4C +{0x4D, 0x00, 0x02}, //Reg 0x4D +{0x4E, 0x00, 0x00}, //Reg 0x4E +{0x5C, 0x00, 0x52}, //Reg 0x5C +{0x5E, 0x00, 0x10}, //Reg 0x5E +{0x34, 0x00, 0xD0}, //Reg 0x34 +{0xD0, 0x00, 0x01}, //Reg 0xD0 + +{0x4F, 0x00, 0x80}, //Reg 0x4F +{0xA1, 0x00, 0xF4}, //Reg 0xA1 +{0xA2, 0x7F, 0x00}, //Reg 0xA2 +{0xBD, 0x00, 0xA0}, //Reg 0xBD +{0xD1, 0xFF, 0x00}, //Reg 0xD1 +{0xD3, 0xFE, 0x01}, //Reg 0xD3 +{0xD4, 0x18, 0x20}, //Reg 0xD4 +{0xD5, 0xF0, 0x00}, //Reg 0xD5 +{0xDD, 0xFF, 0x00}, //Reg 0xDD +{0xDE, 0xEC, 0x10}, //Reg 0xDE +{0xDF, 0xFF, 0x00}, //Reg 0xDF +{0xE0, 0xF7, 0x00}, //Reg 0xE0 +{0xE3, 0xEF, 0x10}, //Reg 0xE3 +{0xE4, 0x7F, 0x80}, //Reg 0xE4 +{0xE5, 0xFF, 0x00}, //Reg 0xE5 +{0xE6, 0x06, 0x00}, //Reg 0xE6 +{0xE7, 0xFF, 0x00}, //Reg 0xE7 +{0xF5, 0x00, 0x00}, //Reg 0xF5 +{0xF6, 0x3F, 0x00}, //Reg 0xF6 +{0xF7, 0xFF, 0x00}, //Reg 0xF7 +{0xFD, 0xFF, 0x00}, //Reg 0xFD +{0x4F, 0x00, 0x00}, //Reg 0x4F +{0x00, 0x00, 0x00} //End of table +}; +uint8_t SiS_ACPI_init[10][3]={ +{0x1B, 0xBF, 0x40}, //Reg 0x1B +{0x84, 0x00, 0x0E}, //Reg 0x84 +{0x85, 0x00, 0x29}, //Reg 0x85 +{0x86, 0x00, 0xCB}, //Reg 0x86 +{0x87, 0x00, 0x55}, //Reg 0x87 +{0x6B, 0x00, 0x00}, //Reg 0x6B +{0x6C, 0x68, 0x97}, //Reg 0x6C +{0x6E, 0x00, 0x00}, //Reg 0x6E +{0x6F, 0xFF, 0x14}, //Reg 0x6F +{0x00, 0x00, 0x00} //End of table +}; +uint8_t SiS_SBPCIE_init[13][3]={ +{0x48, 0x00 ,0x07}, //Reg 0x48 +{0x49, 0x00 ,0x06}, //Reg 0x49 +{0x4A, 0x00 ,0x0C}, //Reg 0x4A +{0x4B, 0x00 ,0x00}, //Reg 0x4B +{0x4E, 0x00 ,0x20}, //Reg 0x4E +{0x1C, 0x00 ,0xF1}, //Reg 0x1C +{0x1D, 0x00 ,0x01}, //Reg 0x1D +{0x24, 0x00 ,0x01}, //Reg 0x24 +{0x26, 0x00 ,0x01}, //Reg 0x26 +{0xF6, 0x00 ,0x02}, //Reg 0xF6 +{0xF7, 0x00 ,0xC8}, //Reg 0xF7 +{0x5B, 0x00 ,0x40}, //Reg 0x5B +{0x00, 0x00, 0x00} //End of table +}; + + +#if 1 +uint8_t SiS_NB_init[56][3]={ +{0x04, 0x00 ,0x07}, //Reg 0x04 +{0x05, 0x00 ,0x00}, //Reg 0x05 // alex +{0x0D, 0x00 ,0x20}, //Reg 0x0D +{0x2C, 0x00 ,0x39}, //Reg 0x2C +{0x2D, 0x00 ,0x10}, //Reg 0x2D +{0x2E, 0x00 ,0x61}, //Reg 0x2E +{0x2F, 0x00 ,0x07}, //Reg 0x2F +{0x34, 0x00 ,0xA0}, //Reg 0x34 +{0x40, 0x00 ,0x36}, //Reg 0x40 +{0x42, 0x00 ,0xB9}, //Reg 0x42 +{0x43, 0x00 ,0x8B}, //Reg 0x43 +{0x44, 0x00 ,0x05}, //Reg 0x44 +{0x45, 0x00 ,0xFF}, //Reg 0x45 +{0x46, 0x00 ,0x90}, //Reg 0x46 +{0x47, 0x00 ,0xA0}, //Reg 0x47 +//{0x4C, 0xFF ,0x09}, //Reg 0x4C // SiS307 enable +{0x4E, 0x00 ,0x00}, //Reg 0x4E +{0x4F, 0x00 ,0x02}, //Reg 0x4F +{0x5B, 0x00 ,0x44}, //Reg 0x5B +{0x5D, 0x00 ,0x00}, //Reg 0x5D +{0x5E, 0x00 ,0x25}, //Reg 0x5E +{0x61, 0x00 ,0xB0}, //Reg 0x61 +{0x65, 0x00 ,0xB0}, //Reg 0x65 +{0x68, 0x00 ,0x4C}, //Reg 0x68 +{0x69, 0x00 ,0xD0}, //Reg 0x69 +{0x6B, 0x00 ,0x07}, //Reg 0x6B +{0x6C, 0x00 ,0xDD}, //Reg 0x6C +{0x6D, 0x00 ,0xAD}, //Reg 0x6D +{0x6E, 0x00 ,0xE8}, //Reg 0x6E +{0x6F, 0x00 ,0x4D}, //Reg 0x6F +{0x70, 0x00 ,0x00}, //Reg 0x70 +{0x71, 0x00 ,0x80}, //Reg 0x71 +{0x72, 0x00 ,0x00}, //Reg 0x72 +{0x73, 0x00 ,0x00}, //Reg 0x73 +{0x74, 0x00 ,0x01}, //Reg 0x74 +{0x75, 0x00 ,0x10}, //Reg 0x75 +{0x7E, 0x00 ,0x29}, //Reg 0x7E +{0x8B, 0x00 ,0x10}, //Reg 0x8B +{0x8D, 0x00 ,0x03}, //Reg 0x8D +{0xA1, 0x00 ,0xD0}, //Reg 0xA1 +{0xA2, 0x00 ,0x30}, //Reg 0xA2 +{0xA4, 0x00 ,0x0B}, //Reg 0xA4 +{0xA9, 0x00 ,0x02}, //Reg 0xA9 +{0xB0, 0x00 ,0x30}, //Reg 0xB0 +{0xB4, 0x00 ,0x30}, //Reg 0xB4 +{0x90, 0x00 ,0x00}, //Reg 0x90 +{0x91, 0x00 ,0x00}, //Reg 0x91 +{0x92, 0x00 ,0x00}, //Reg 0x92 +{0x93, 0x00 ,0x00}, //Reg 0x93 +{0x94, 0x00 ,0x00}, //Reg 0x94 +{0x95, 0x00 ,0x00}, //Reg 0x95 +{0x96, 0x00 ,0x00}, //Reg 0x96 +{0x97, 0x00 ,0x00}, //Reg 0x97 +{0x98, 0x00 ,0x00}, //Reg 0x98 +{0x99, 0x00 ,0x00}, //Reg 0x99 +// alex +//{0xD7, 0x00 ,0x00}, //Reg 0x99 +//{0xDD, 0x00 ,0x02}, //Reg 0x99 +// +//{0x13, 0x00 ,0xF0}, //Reg 0x99 + +{0x00, 0x00, 0x00} //End of table +}; + +#else +uint8_t SiS_NB_init[61][3]={ +{0x04, 0x00 ,0x07}, //Reg 0x04 +{0x05, 0x00 ,0x00}, //Reg 0x05 // alex +{0x0D, 0x00 ,0x20}, //Reg 0x0D +{0x2C, 0x00 ,0x39}, //Reg 0x2C +{0x2D, 0x00 ,0x10}, //Reg 0x2D +{0x2E, 0x00 ,0x61}, //Reg 0x2E +{0x2F, 0x00 ,0x07}, //Reg 0x2F +{0x34, 0x00 ,0xA0}, //Reg 0x34 +{0x40, 0x00 ,0x36}, //Reg 0x40 +{0x42, 0x00 ,0xB9}, //Reg 0x42 +{0x43, 0x00 ,0x8B}, //Reg 0x43 +{0x44, 0x00 ,0x05}, //Reg 0x44 +{0x45, 0x00 ,0xFF}, //Reg 0x45 +{0x46, 0x00 ,0x90}, //Reg 0x46 +{0x47, 0x00 ,0xA0}, //Reg 0x47 +{0x4C, 0xFF ,0x50}, //Reg 0x4C // SiS307 enable +{0x4E, 0x00 ,0x00}, //Reg 0x4E +{0x4F, 0x00 ,0x02}, //Reg 0x4F +{0x5B, 0x00 ,0x44}, //Reg 0x5B +{0x5D, 0x00 ,0x00}, //Reg 0x5D +{0x5E, 0x00 ,0x25}, //Reg 0x5E +{0x61, 0x00 ,0xB0}, //Reg 0x61 +{0x65, 0x00 ,0xB0}, //Reg 0x65 +{0x68, 0x00 ,0x4C}, //Reg 0x68 +{0x69, 0x00 ,0xD0}, //Reg 0x69 +{0x6B, 0x00 ,0x07}, //Reg 0x6B +{0x6C, 0x00 ,0xDD}, //Reg 0x6C +{0x6D, 0x00 ,0xAD}, //Reg 0x6D +{0x6E, 0x00 ,0xE8}, //Reg 0x6E +{0x6F, 0x00 ,0x4D}, //Reg 0x6F +{0x70, 0x00 ,0x00}, //Reg 0x70 +{0x71, 0x00 ,0x80}, //Reg 0x71 +{0x72, 0x00 ,0x00}, //Reg 0x72 +{0x73, 0x00 ,0x00}, //Reg 0x73 +{0x74, 0x00 ,0x01}, //Reg 0x74 +{0x75, 0x00 ,0x10}, //Reg 0x75 +{0x7E, 0x00 ,0x29}, //Reg 0x7E +{0x8B, 0x00 ,0x10}, //Reg 0x8B +{0x8D, 0x00 ,0x03}, //Reg 0x8D +{0xA1, 0x00 ,0xD0}, //Reg 0xA1 +{0xA2, 0x00 ,0x30}, //Reg 0xA2 +{0xA4, 0x00 ,0x0B}, //Reg 0xA4 +{0xA9, 0x00 ,0x02}, //Reg 0xA9 +{0xB0, 0x00 ,0x30}, //Reg 0xB0 +{0xB4, 0x00 ,0x30}, //Reg 0xB4 +{0x90, 0x00 ,0x00}, //Reg 0x90 +{0x91, 0x00 ,0x00}, //Reg 0x91 +{0x92, 0x00 ,0x00}, //Reg 0x92 +{0x93, 0x00 ,0x00}, //Reg 0x93 +{0x94, 0x00 ,0x00}, //Reg 0x94 +{0x95, 0x00 ,0x00}, //Reg 0x95 +{0x96, 0x00 ,0x00}, //Reg 0x96 +{0x97, 0x00 ,0x00}, //Reg 0x97 +{0x98, 0x00 ,0x00}, //Reg 0x98 +{0x99, 0x00 ,0x00}, //Reg 0x99 +// alex +{0x86, 0x00 ,0x14}, //Reg 0x99 +{0x87, 0x00 ,0xC8}, //Reg 0x99 +{0xF4, 0x00 ,0x01}, +// +{0x13, 0x00 ,0xF0}, //Reg 0x99 + +{0x00, 0x00, 0x00} //End of table +}; + + +#endif +#if 1 +uint8_t SiS_NBAGP_init[34][3]={ +{0xCF, 0xDF, 0x00}, //HT issue +{0x06, 0xDF, 0x20}, +{0x1E, 0xDF, 0x20}, +{0x50, 0x00, 0x02}, +{0x51, 0x00, 0x00}, +{0x54, 0x00, 0x09}, +{0x55, 0x00, 0x00}, +{0x56, 0x00, 0x80}, +{0x58, 0x00, 0x08}, +{0x60, 0x00, 0xB1}, +{0x61, 0x00, 0x02}, +{0x62, 0x00, 0x60}, +{0x63, 0x00, 0x60}, +{0x64, 0x00, 0xAA}, +{0x65, 0x00, 0x18}, +{0x68, 0x00, 0x23}, +{0x69, 0x00, 0x23}, +{0x6A, 0x00, 0xC8}, +{0x6B, 0x00, 0x08}, +{0x6C, 0x00, 0x00}, +{0x6D, 0x00, 0x00}, +{0x6E, 0x00, 0x08}, +{0x6F, 0x00, 0x00}, +{0xBB, 0x00, 0x00}, +{0xB5, 0x00, 0x30}, +{0xB0, 0x00, 0xDB}, +{0xB6, 0x00, 0x73}, +{0xB7, 0x00, 0x50}, +{0xBA, 0xBF, 0x41}, +{0xB4, 0x3F, 0xC0}, +{0xBF, 0xF9, 0x06}, +{0xBA, 0x00, 0x61}, +{0xBD, 0x7F, 0x80}, + + +{0x00, 0x00, 0x00} //End of table +}; + + + +#else + +//uint8_t SiS_NBAGP_init[53][3]={ +uint8_t SiS_NBAGP_init[40][3]={ +{0x04, 0x00 ,0x07}, //Reg 0x04 +{0x05, 0x00 ,0x01}, //Reg 0x05 // alex + +{0xCF, 0xDF, 0x00}, //HT issue +{0x06, 0xDF, 0x20}, +{0x1E, 0xDF, 0x20}, +{0x50, 0x00, 0x02}, +{0x51, 0x00, 0x00}, +{0x54, 0x00, 0x09}, +{0x55, 0x00, 0x00}, +{0x56, 0x00, 0x80}, +{0x58, 0x00, 0x08}, +{0x60, 0x00, 0xB1}, +{0x61, 0x00, 0x02}, +{0x62, 0x00, 0x60}, +{0x63, 0x00, 0x60}, +{0x64, 0x00, 0xAA}, +{0x65, 0x00, 0x18}, +{0x68, 0x00, 0x23}, +{0x69, 0x00, 0x23}, +{0x6A, 0x00, 0xC8}, +{0x6B, 0x00, 0x08}, +{0x6C, 0x00, 0x00}, +{0x6D, 0x00, 0x00}, +{0x6E, 0x00, 0x08}, +{0x6F, 0x00, 0x00}, +{0xBB, 0x00, 0x00}, +{0xB5, 0x00, 0x30}, +{0xB0, 0x00, 0xDB}, +{0xB6, 0x00, 0x73}, +{0xB7, 0x00, 0x50}, +{0xBA, 0xBF, 0x41}, +{0xB4, 0x3F, 0xC0}, +{0xBF, 0xF9, 0x06}, +{0xBA, 0x00, 0x61}, +{0xBD, 0x7F, 0x80}, + + + +{0x0D, 0x00 ,0x40}, //Reg 0x05 // alex +/* +{0x19, 0x00 ,0x01}, //Reg 0x05 // alex +{0x1A, 0x00 ,0x01}, //Reg 0x05 // alex +{0x1B, 0x00 ,0x40}, //Reg 0x05 // alex +{0x1C, 0x00 ,0xE0}, //Reg 0x05 // alex +{0x1D, 0x00 ,0xE0}, //Reg 0x05 // alex +{0x20, 0x00 ,0xB0}, //Reg 0x05 // alex +{0x21, 0x00 ,0xFE}, //Reg 0x05 // alex +{0x22, 0x00 ,0xB0}, //Reg 0x05 // alex +{0x23, 0x00 ,0xFE}, //Reg 0x05 // alex +{0x24, 0x00 ,0x00}, //Reg 0x05 // alex +{0x25, 0x00 ,0xD8}, //Reg 0x05 // alex +{0x26, 0x00 ,0xF0}, //Reg 0x05 // alex +{0x27, 0x00 ,0xDF}, //Reg 0x05 // alex +*/ +{0x3E, 0x00 ,0x0A}, //Reg 0x05 // alex + +{0xCB, 0x00 ,0x10}, //Reg 0x05 // alex +{0xCF, 0x00 ,0x48}, //Reg 0x05 // alex + + +{0x00, 0x00, 0x00} //End of table +}; + +#endif + +uint8_t SiS_ACPI_2_init[56][3]={ +{0x00, 0x00, 0xFF}, //Reg 0x00 +{0x01, 0x00, 0xFF}, //Reg 0x01 +{0x02, 0x00, 0x00}, //Reg 0x02 +{0x03, 0x00, 0x00}, //Reg 0x03 +{0x16, 0x00, 0x00}, //Reg 0x16 +{0x20, 0x00, 0xFF}, //Reg 0x20 +{0x21, 0x00, 0xFF}, //Reg 0x21 +{0x22, 0x00, 0x00}, //Reg 0x22 +{0x23, 0x00, 0x00}, //Reg 0x23 +{0x24, 0x00, 0x55}, //Reg 0x24 +{0x25, 0x00, 0x55}, //Reg 0x25 +{0x26, 0x00, 0x55}, //Reg 0x26 +{0x27, 0x00, 0x55}, //Reg 0x27 +{0x2A, 0x00, 0x40}, //Reg 0x2A +{0x2B, 0x00, 0x10}, //Reg 0x2B +{0x2E, 0x00, 0xFF}, //Reg 0x2E +{0x30, 0x00, 0xFF}, //Reg 0x30 +{0x31, 0x00, 0xFF}, //Reg 0x31 +{0x32, 0x00, 0x00}, //Reg 0x32 +{0x33, 0x00, 0x00}, //Reg 0x33 +{0x40, 0x00, 0xFF}, //Reg 0x40 +{0x41, 0x00, 0xFF}, //Reg 0x41 +{0x42, 0x00, 0x00}, //Reg 0x42 +{0x43, 0x00, 0x00}, //Reg 0x43 +{0x4A, 0x00, 0x00}, //Reg 0x4A +{0x4E, 0x00, 0x0F}, //Reg 0x4E +{0x5A, 0x00, 0x00}, //Reg 0x5A +{0x5B, 0x00, 0x00}, //Reg 0x5B +{0x62, 0x00, 0x00}, //Reg 0x62 +{0x63, 0x00, 0x04}, //Reg 0x63 +{0x68, 0x00, 0xFF}, //Reg 0x68 +{0x76, 0x00, 0xA0}, //Reg 0x76 +{0x77, 0x00, 0x22}, //Reg 0x77 +{0x78, 0xDF, 0x20}, //Reg 0x78 +{0x7A, 0x00, 0x10}, //Reg 0x7A +{0x7C, 0x00, 0x45}, //Reg 0x7C +{0x7D, 0x00, 0xB8}, //Reg 0x7D +{0x7F, 0x00, 0x00}, //Reg 0x7F +{0x80, 0x00, 0x1C}, //Reg 0x80 +{0x82, 0x00, 0x01}, //Reg 0x82 +{0x84, 0x00, 0x0E}, //Reg 0x84 +{0x85, 0x00, 0x29}, //Reg 0x85 +{0x86, 0x00, 0xCB}, //Reg 0x86 +{0x87, 0x00, 0x55}, //Reg 0x87 +{0x88, 0x00, 0x04}, //Reg 0x88 +{0x96, 0x00, 0x80}, //Reg 0x96 +{0x99, 0x00, 0x80}, //Reg 0x99 +{0x9A, 0x00, 0x15}, //Reg 0x9A +{0x9D, 0x00, 0x05}, //Reg 0x9D +{0x9E, 0x00, 0x00}, //Reg 0x9E +{0x9F, 0x00, 0x04}, //Reg 0x9F +{0xB0, 0x00, 0x6D}, //Reg 0xB0 +{0xB1, 0x00, 0x8C}, //Reg 0xB1 +{0xB9, 0x00, 0xFF}, //Reg 0xB9 +{0xBA, 0x00, 0x3F}, //Reg 0xBA +{0x00, 0x00, 0x00} //End of table +}; + +#if 0 +uint8_t SiS_SiS1183_init[60][3]={ +{0x04, 0x00, 0x05}, +{0x09, 0x00, 0x05}, +{0x2C, 0x00, 0x39}, +{0x2D, 0x00, 0x10}, +{0x2E, 0x00, 0x83}, +{0x2F, 0x00, 0x11}, +{0x90, 0x00, 0x40}, +{0x91, 0x00, 0x00}, // set mode +{0x50, 0x00, 0xA2}, +{0x52, 0x00, 0xA2}, +{0x55, 0x00, 0x96}, +{0x52, 0x00, 0xA2}, +{0x55, 0xF7, 0x00}, +{0x56, 0x00, 0xC0}, +{0x57, 0x00, 0x14}, +{0x67, 0x00, 0x28}, +{0x81, 0x00, 0xB3}, +{0x82, 0x00, 0x72}, +{0x83, 0x00, 0x40}, +{0x85, 0x00, 0xB3}, +{0x86, 0x00, 0x72}, +{0x87, 0x00, 0x40}, +{0x88, 0x00, 0xDE}, // after set mode +{0x89, 0x00, 0xB3}, +{0x8A, 0x00, 0x72}, +{0x8B, 0x00, 0x40}, +{0x8C, 0x00, 0xDE}, +{0x8D, 0x00, 0xB3}, +{0x8E, 0x00, 0x92}, +{0x8F, 0x00, 0x40}, +{0x93, 0x00, 0x00}, +{0x94, 0x00, 0x80}, +{0x95, 0x00, 0x08}, +{0x96, 0x00, 0x80}, +{0x97, 0x00, 0x08}, +{0x9C, 0x00, 0x80}, +{0x9D, 0x00, 0x08}, +{0x9E, 0x00, 0x80}, +{0x9F, 0x00, 0x08}, +{0xA0, 0x00, 0x15}, +{0xA1, 0x00, 0x15}, +{0xA2, 0x00, 0x15}, +{0xA3, 0x00, 0x15}, + +//{0xD8, 0xFE, 0x01}, // Com reset +//{0xC8, 0xFE, 0x01}, +//{0xE8, 0xFE, 0x01}, +//{0xF8, 0xFE, 0x01}, +{0xC4, 0xFF, 0xFF}, // Clear status +{0xC5, 0xFF, 0xFF}, +{0xC6, 0xFF, 0xFF}, +{0xC7, 0xFF, 0xFF}, +{0xD4, 0xFF, 0xFF}, +{0xD5, 0xFF, 0xFF}, +{0xD6, 0xFF, 0xFF}, +{0xD7, 0xFF, 0xFF}, +{0xE4, 0xFF, 0xFF}, // Clear status +{0xE5, 0xFF, 0xFF}, +{0xE6, 0xFF, 0xFF}, +{0xE7, 0xFF, 0xFF}, +{0xF4, 0xFF, 0xFF}, +{0xF5, 0xFF, 0xFF}, +{0xF6, 0xFF, 0xFF}, +{0xF7, 0xFF, 0xFF}, +{0x00, 0x00, 0x00} //End of table +}; + +#else + +uint8_t SiS_SiS1183_init[44][3]={ +{0x04, 0x00, 0x05}, +{0x09, 0x00, 0x05}, +{0x2C, 0x00, 0x39}, +{0x2D, 0x00, 0x10}, +{0x2E, 0x00, 0x83}, +{0x2F, 0x00, 0x11}, +{0x90, 0x00, 0x40}, +{0x91, 0x00, 0x00}, // set mode +{0x50, 0x00, 0xA2}, +{0x52, 0x00, 0xA2}, +{0x55, 0x00, 0x96}, +{0x52, 0x00, 0xA2}, +{0x55, 0xF7, 0x00}, +{0x56, 0x00, 0xC0}, +{0x57, 0x00, 0x14}, +{0x67, 0x00, 0x28}, +{0x81, 0x00, 0xB3}, +{0x82, 0x00, 0x72}, +{0x83, 0x00, 0x40}, +{0x85, 0x00, 0xB3}, +{0x86, 0x00, 0x72}, +{0x87, 0x00, 0x40}, +{0x88, 0x00, 0xDE}, // after set mode +{0x89, 0x00, 0xB3}, +{0x8A, 0x00, 0x72}, +{0x8B, 0x00, 0x40}, +{0x8C, 0x00, 0xDE}, +{0x8D, 0x00, 0xB3}, +{0x8E, 0x00, 0x92}, +{0x8F, 0x00, 0x40}, +{0x93, 0x00, 0x00}, +{0x94, 0x00, 0x80}, +{0x95, 0x00, 0x08}, +{0x96, 0x00, 0x80}, +{0x97, 0x00, 0x08}, +{0x9C, 0x00, 0x80}, +{0x9D, 0x00, 0x08}, +{0x9E, 0x00, 0x80}, +{0x9F, 0x00, 0x08}, +{0xA0, 0x00, 0x15}, +{0xA1, 0x00, 0x15}, +{0xA2, 0x00, 0x15}, +{0xA3, 0x00, 0x15}, + + +{0x00, 0x00, 0x00} //End of table +}; + +#endif + +/* In => Share Memory size + => 00h : 0MBytes + => 02h : 32MBytes + => 03h : 64MBytes + => 04h : 128MBytes + => Others: Reserved +*/ +void Init_Share_Memory(uint8_t ShareSize) +{ + device_t dev; + + dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_SIS, PCI_DEVICE_ID_SIS_SIS761), 0); + pci_write_config8(dev, 0x4C, (pci_read_config8(dev, 0x4C) & 0x1F) | (ShareSize << 5)); +} + +/* In: => Aperture size + => 00h : 32MBytes + => 01h : 64MBytes + => 02h : 128MBytes + => 03h : 256MBytes + => 04h : 512MBytes + => Others: Reserved +*/ +void Init_Aper_Size(uint8_t AperSize) +{ + device_t dev; + uint16_t SiSAperSizeTable[]={0x0F38, 0x0F30, 0x0F20, 0x0F00, 0x0E00}; + + dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_AMD, 0x1103), 0); + pci_write_config8(dev, 0x90, AperSize << 1); + +//pci_write_config32(dev, 0x94, 0x78); +//pci_write_config32(dev, 0x98, 0x0); + +#if 0 +{ +int i; +print_debug("Function3 Config in sis_init_stage2\n"); +for(i=0;i<0xFF;i+=4) +{ if((i%16)==0) + {print_debug("\r\n");print_debug_hex8(i);print_debug(" ");} + print_debug_hex32(pci_read_config32(dev,i)); + print_debug(" "); +} +print_debug("\n"); +} +#endif + +dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_SIS, PCI_DEVICE_ID_SIS_SIS761), 0); +pci_write_config16(dev, 0xB4, SiSAperSizeTable[AperSize]); + +#if 0 +{ +int i; +dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_AMD, 0x1101), 0); +print_debug("Function1 Config in sis_init_stage2\n"); +for(i=0;i<0xFF;i+=4) +{ if((i%16)==0) + {print_debug("\r\n");print_debug_hex8(i);print_debug(" ");} + print_debug_hex32(pci_read_config32(dev,i)); + print_debug(" "); +} +print_debug("\n"); +} + + #endif + + +} + + + + + +void sis_init_stage1(void) +{ + device_t dev; + uint8_t temp8; + int i; + uint8_t GUI_En; + +#if 0 +{ +int i; +print_debug("Northbridge PCI Config in sis_init_stage1.0\n"); +for(i=0;i<0xFF;i+=4) +{ if((i%16)==0) + {print_debug("\r\n");print_debug_hex8(i);print_debug(" ");} + print_debug_hex32(pci_read_config32(dev,i)); + print_debug(" "); +} +print_debug("\n"); +} +#endif + +// SiS_Chipset_Initialization +// ========================== NB ============================= + dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_SIS, PCI_DEVICE_ID_SIS_SIS761), 0); + i=0; + while(SiS_NB_init[i][0] != 0) + { temp8 = pci_read_config8(dev, SiS_NB_init[i][0]); + temp8 &= SiS_NB_init[i][1]; + temp8 |= SiS_NB_init[i][2]; + pci_write_config8(dev, SiS_NB_init[i][0], temp8); + i++; + }; + + +#if 0 +{ +int i; +print_debug("Northbridge PCI Config in sis_init_stage1.1\n"); +for(i=0;i<0xFF;i+=4) +{ if((i%16)==0) + {print_debug("\r\n");print_debug_hex8(i);print_debug(" ");} + print_debug_hex32(pci_read_config32(dev,i)); + print_debug(" "); +} +print_debug("\n"); +} +#endif + + + +// ========================== LPC ============================= + dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_SIS, PCI_DEVICE_ID_SIS_SIS966_LPC), 0); + i=0; + while(SiS_LPC_init[i][0] != 0) + { temp8 = pci_read_config8(dev, SiS_LPC_init[i][0]); + temp8 &= SiS_LPC_init[i][1]; + temp8 |= SiS_LPC_init[i][2]; + pci_write_config8(dev, SiS_LPC_init[i][0], temp8); + i++; + }; +// ========================== ACPI ============================= + i=0; + while(SiS_ACPI_init[i][0] != 0) + { temp8 = inb(0x800 + SiS_ACPI_init[i][0]); + temp8 &= SiS_ACPI_init[i][1]; + temp8 |= SiS_ACPI_init[i][2]; + outb(temp8, 0x800 + SiS_ACPI_init[i][0]); + i++; + }; +// ========================== NBPCIE ============================= + dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_SIS, PCI_DEVICE_ID_SIS_SIS761), 0); //Disable Internal GUI enable bit + temp8 = pci_read_config8(dev, 0x4C); + GUI_En = temp8 & 0x10; + pci_write_config8(dev, 0x4C, temp8 & (!0x10)); + + dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_SIS, 0x0004), 0); + i=0; + while(SiS_NBPCIE_init[i][0] != 0) + { temp8 = pci_read_config8(dev, SiS_NBPCIE_init[i][0]); + temp8 &= SiS_NBPCIE_init[i][1]; + temp8 |= SiS_NBPCIE_init[i][2]; + pci_write_config8(dev, SiS_NBPCIE_init[i][0], temp8); + i++; + }; + dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_SIS, PCI_DEVICE_ID_SIS_SIS761), 0); //Restore Internal GUI enable bit + temp8 = pci_read_config8(dev, 0x4C); + pci_write_config8(dev, 0x4C, temp8 | GUI_En); + + return; +} + + + +void sis_init_stage2(void) +{ + device_t dev; + msr_t msr; + int i; + uint32_t j; + uint8_t temp8; + uint16_t temp16; + + +// ========================== NB_AGP ============================= + dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_SIS, PCI_DEVICE_ID_SIS_SIS761), 0); //Enable Internal GUI enable bit + pci_write_config8(dev, 0x4C, pci_read_config8(dev, 0x4C) | 0x10); + + dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_SIS, 0x0002), 0); + i=0; + while(SiS_NBAGP_init[i][0] != 0) + { temp8 = pci_read_config8(dev, SiS_NBAGP_init[i][0]); + temp8 &= SiS_NBAGP_init[i][1]; + temp8 |= SiS_NBAGP_init[i][2]; + pci_write_config8(dev, SiS_NBAGP_init[i][0], temp8); + i++; + }; + +/* In => Share Memory size + => 00h : 0MBytes + => 02h : 32MBytes + => 03h : 64MBytes + => 04h : 128MBytes + => Others: Reserved +*/ +/* In: => Aperture size + => 00h : 32MBytes + => 01h : 64MBytes + => 02h : 128MBytes + => 03h : 256MBytes + => 04h : 512MBytes + => Others: Reserved +*/ + + Init_Share_Memory(0x02); //0x02 : 32M 0x03 : 64M + Init_Aper_Size(0x01); // 0x1 + +#if 0 +{ +int i; +print_debug("AGP PCI Config in sis_init_stage2\n"); +for(i=0;i<0xFF;i+=4) +{ if((i%16)==0) + {print_debug("\r\n");print_debug_hex8(i);print_debug(" ");} + print_debug_hex32(pci_read_config32(dev,i)); + print_debug(" "); +} +print_debug("\n"); +} +#endif + + +// ========================== NB ============================= + + printk_debug("Init NorthBridge sis761 -------->\n"); + dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_SIS, PCI_DEVICE_ID_SIS_SIS761), 0); + msr = rdmsr(0xC001001A); + printk_debug("Memory Top Bound %lx\n",msr.lo ); +// pci_write_config16(dev, 0x8E, msr.lo >> 16); // Topbound +// pci_write_config16(dev, 0x8E, (msr.lo >> 16) - ((pci_read_config8(dev, 0x4C) & 0xE0) >> 5)); + + temp16=(pci_read_config8(dev, 0x4C) & 0xE0) >> 5; + //printk_debug("0x4c = %x\n",temp16); + temp16=0x0001<<(temp16-1); + temp16<<=8; + + printk_debug("Integrated VGA Shared memory size=%dM bytes\n", temp16 >> 4); + pci_write_config16(dev, 0x8E, (msr.lo >> 16) -temp16*1); + // pci_write_config16(dev, 0x8E, (msr.lo >> 16) -temp16); + pci_write_config8(dev, 0x7F, 0x08); // ACPI Base + outb(inb(0x856) | 0x40, 0x856); // Auto-Reset Function + +#if 0 +{ +int i; +print_debug("Northbridge PCI Config in sis_init_stage2\n"); +for(i=0;i<0xFF;i+=4) +{ if((i%16)==0) + {print_debug("\r\n");print_debug_hex8(i);print_debug(" ");} + print_debug_hex32(pci_read_config32(dev,i)); + print_debug(" "); +} +print_debug("\n"); +} +#endif + + + + +// ========================== ACPI ============================= + i=0; + printk_debug("Init ACPI -------->\n"); + do + { temp8 = inb(0x800 + SiS_ACPI_2_init[i][0]); + temp8 &= SiS_ACPI_2_init[i][1]; + temp8 |= SiS_ACPI_2_init[i][2]; + outb(temp8, 0x800 + SiS_ACPI_2_init[i][0]); + i++; + }while(SiS_ACPI_2_init[i][0] != 0); + +// ========================== Misc ============================= + printk_debug("Init Misc -------->\n"); + dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_SIS, PCI_DEVICE_ID_SIS_SIS966_ISA), 0); + // PCI Device Enable + pci_write_config8(dev, 0x7C, 0x03); // bit0=0 : enable audio controller(), bit1=1 : disable modem + pci_write_config8(dev, 0x76, pci_read_config8(dev, 0x76)|0x30); // SM bus enable, PCIEXP Controller 1 and 2 disable + pci_write_config8(dev, 0x7E, 0x00); // azalia controller enable + + temp8=inb(0x878)|0x4; //bit2=1 enable Azalia =0 enable AC97 + outb(temp8, 0x878); // ACPI select AC97 or HDA controller + printk_debug("Audio select %x\n",inb(0x878)); + + dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_SIS, 0x1183), 0); + if(!dev){ + print_debug("SiS 1183 does not exist !!"); + } + // SATA Set Mode + pci_write_config8(dev, 0x90, (pci_read_config8(dev, 0x90)&0x3F) | 0x40); + + +//-------------- enable IDE (SiS1183) ------------------------- +/* +{ + uint8_t temp8; + int i=0; + while(SiS_SiS1183_init[i][0] != 0) + { temp8 = pci_read_config8(dev, SiS_SiS1183_init[i][0]); + temp8 &= SiS_SiS1183_init[i][1]; + temp8 |= SiS_SiS1183_init[i][2]; + pci_write_config8(dev, SiS_SiS1183_init[i][0], temp8); + i++; + }; +} + +*/ + +} + + + +static void enable_smbus(void) +{ + device_t dev; + uint8_t temp8; + printk_debug("enable_smbus -------->\n"); + + dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_SIS, PCI_DEVICE_ID_SIS_SIS966_LPC), 0); + + /* set smbus iobase && enable ACPI Space*/ + pci_write_config16(dev, 0x74, 0x0800); // Set ACPI Base + temp8=pci_read_config8(dev, 0x40); // Enable ACPI Space + pci_write_config8(dev, 0x40, temp8 | 0x80); + temp8=pci_read_config8(dev, 0x76); // Enable SMBUS + pci_write_config8(dev, 0x76, temp8 | 0x03); + + printk_debug("enable_smbus <--------\n"); +} + +static int smbus_read_byte(unsigned device, unsigned address) +{ + return do_smbus_read_byte(SMBUS0_IO_BASE, device, address); +} +static int smbus_write_byte(unsigned device, unsigned address, unsigned char val) +{ + return do_smbus_write_byte(SMBUS0_IO_BASE, device, address, val); +} + diff --git a/src/southbridge/sis/sis966/sis966_enable_rom.c b/src/southbridge/sis/sis966/sis966_enable_rom.c new file mode 100644 index 0000000000..f0b1f9f242 --- /dev/null +++ b/src/southbridge/sis/sis966/sis966_enable_rom.c @@ -0,0 +1,41 @@ +/* + * This file is part of the LinuxBIOS project. + * + * Copyright (C) 2004 Tyan Computer + * Written by Yinghai Lu for Tyan Computer. + * Copyright (C) 2006,2007 AMD + * Written by Yinghai Lu for AMD. + * Copyright (C) 2007 Silicon Integrated Systems Corp. (SiS) + * Written by Morgan Tsai for SiS. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#if HT_CHAIN_END_UNITID_BASE < HT_CHAIN_UNITID_BASE + #define SIS966_DEVN_BASE HT_CHAIN_END_UNITID_BASE +#else + #define SIS966_DEVN_BASE HT_CHAIN_UNITID_BASE +#endif + +static void sis966_enable_rom(void) +{ + device_t addr; + + /* Enable 4MB rom access at 0xFFC00000 - 0xFFFFFFFF */ + addr = pci_locate_device(PCI_ID(0x1039, 0x0966), 0); + + /* Set the 4MB enable bit bit */ + pci_write_config8(addr, 0x40, pci_read_config8(addr, 0x40) | 0x11); +} diff --git a/src/southbridge/sis/sis966/sis966_enable_usbdebug_direct.c b/src/southbridge/sis/sis966/sis966_enable_usbdebug_direct.c new file mode 100644 index 0000000000..07b10fea4c --- /dev/null +++ b/src/southbridge/sis/sis966/sis966_enable_usbdebug_direct.c @@ -0,0 +1,50 @@ +/* + * This file is part of the LinuxBIOS project. + * + * Copyright (C) 2004 Tyan Computer + * Written by Yinghai Lu for Tyan Computer. + * Copyright (C) 2006,2007 AMD + * Written by Yinghai Lu for AMD. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#if HT_CHAIN_END_UNITID_BASE < HT_CHAIN_UNITID_BASE + #define SIS966_DEVN_BASE HT_CHAIN_END_UNITID_BASE +#else + #define SIS966_DEVN_BASE HT_CHAIN_UNITID_BASE +#endif + +#define EHCI_BAR_INDEX 0x10 +#define EHCI_BAR 0xFEF00000 +#define EHCI_DEBUG_OFFSET 0x98 + +static void set_debug_port(unsigned port) +{ + uint32_t dword; + dword = pci_read_config32(PCI_DEV(0, SIS966_DEVN_BASE+2, 1), 0x74); + dword &= ~(0xf<<12); + dword |= (port<<12); + pci_write_config32(PCI_DEV(0, SIS966_DEVN_BASE+2, 1), 0x74, dword); + +} + +static void sis966_enable_usbdebug_direct(unsigned port) +{ + set_debug_port(port); + pci_write_config32(PCI_DEV(0, SIS966_DEVN_BASE+2, 1), EHCI_BAR_INDEX, EHCI_BAR); + pci_write_config8(PCI_DEV(0, SIS966_DEVN_BASE+2, 1), 0x04, 0x2); // mem space enabe +} + diff --git a/src/southbridge/sis/sis966/sis966_ht.c b/src/southbridge/sis/sis966/sis966_ht.c new file mode 100644 index 0000000000..702138d8da --- /dev/null +++ b/src/southbridge/sis/sis966/sis966_ht.c @@ -0,0 +1,56 @@ +/* + * This file is part of the LinuxBIOS project. + * + * Copyright (C) 2004 Tyan Computer + * Written by Yinghai Lu for Tyan Computer. + * Copyright (C) 2006,2007 AMD + * Written by Yinghai Lu for AMD. + * Copyright (C) 2007 Silicon Integrated Systems Corp. (SiS) + * Written by Morgan Tsai for SiS. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include "sis966.h" + +static void lpci_set_subsystem(device_t dev, unsigned vendor, unsigned device) +{ + pci_write_config32(dev, 0x40, + ((device & 0xffff) << 16) | (vendor & 0xffff)); +} +static struct pci_operations lops_pci = { + .set_subsystem = lpci_set_subsystem, +}; + +static struct device_operations ht_ops = { + .read_resources = pci_dev_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_dev_enable_resources, + .init = 0, + .scan_bus = 0, + .ops_pci = &lops_pci, +}; + +static struct pci_driver ht_driver __pci_driver = { + .ops = &ht_ops, + .vendor = PCI_VENDOR_ID_SIS, + .device = PCI_DEVICE_ID_SIS_SIS966_HT, +}; + diff --git a/src/southbridge/sis/sis966/sis966_ide.c b/src/southbridge/sis/sis966/sis966_ide.c new file mode 100644 index 0000000000..0b2b3439aa --- /dev/null +++ b/src/southbridge/sis/sis966/sis966_ide.c @@ -0,0 +1,175 @@ +/* + * This file is part of the LinuxBIOS project. + * + * Copyright (C) 2004 Tyan Computer + * Written by Yinghai Lu for Tyan Computer. + * Copyright (C) 2006,2007 AMD + * Written by Yinghai Lu for AMD. + * Copyright (C) 2007 Silicon Integrated Systems Corp. (SiS) + * Written by Morgan Tsai for SiS. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include +#include "sis966.h" + +uint8_t SiS_SiS5513_init[49][3]={ +{0x04, 0xFF, 0x05}, +{0x0D, 0xFF, 0x80}, +{0x2C, 0xFF, 0x39}, +{0x2D, 0xFF, 0x10}, +{0x2E, 0xFF, 0x13}, +{0x2F, 0xFF, 0x55}, +{0x50, 0xFF, 0xA2}, +{0x51, 0xFF, 0x21}, +{0x53, 0xFF, 0x21}, +{0x54, 0xFF, 0x2A}, +{0x55, 0xFF, 0x96}, +{0x52, 0xFF, 0xA2}, +{0x56, 0xFF, 0x81}, +{0x57, 0xFF, 0xC0}, +{0x60, 0xFF, 0xFB}, +{0x61, 0xFF, 0xAA}, +{0x62, 0xFF, 0xFB}, +{0x63, 0xFF, 0xAA}, +{0x81, 0xFF, 0xB3}, +{0x82, 0xFF, 0x72}, +{0x83, 0xFF, 0x40}, +{0x85, 0xFF, 0xB3}, +{0x86, 0xFF, 0x72}, +{0x87, 0xFF, 0x40}, +{0x94, 0xFF, 0xC0}, +{0x95, 0xFF, 0x08}, +{0x96, 0xFF, 0xC0}, +{0x97, 0xFF, 0x08}, +{0x98, 0xFF, 0xCC}, +{0x99, 0xFF, 0x04}, +{0x9A, 0xFF, 0x0C}, +{0x9B, 0xFF, 0x14}, +{0xA0, 0xFF, 0x11}, +{0x57, 0xFF, 0xD0}, + +{0xD8, 0xFE, 0x01}, // Com reset +{0xC8, 0xFE, 0x01}, +{0xC4, 0xFF, 0xFF}, // Clear status +{0xC5, 0xFF, 0xFF}, +{0xC6, 0xFF, 0xFF}, +{0xC7, 0xFF, 0xFF}, +{0xD4, 0xFF, 0xFF}, +{0xD5, 0xFF, 0xFF}, +{0xD6, 0xFF, 0xFF}, +{0xD7, 0xFF, 0xFF}, + + +{0x2C, 0xFF, 0x39}, // set subsystem ID +{0x2D, 0xFF, 0x10}, +{0x2E, 0xFF, 0x13}, +{0x2F, 0xFF, 0x55}, + + +{0x00, 0x00, 0x00} //End of table +}; + +static void ide_init(struct device *dev) +{ + struct southbridge_sis_sis966_config *conf; + /* Enable ide devices so the linux ide driver will work */ + uint32_t dword; + uint16_t word; + uint8_t byte; + conf = dev->chip_info; + + + +printk_debug("ide_init:---------->\n"); + + +//-------------- enable IDE (SiS5513) ------------------------- +{ + uint8_t temp8; + int i=0; + while(SiS_SiS5513_init[i][0] != 0) + { temp8 = pci_read_config8(dev, SiS_SiS5513_init[i][0]); + temp8 &= SiS_SiS5513_init[i][1]; + temp8 |= SiS_SiS5513_init[i][2]; + pci_write_config8(dev, SiS_SiS5513_init[i][0], temp8); + i++; + }; +} +//----------------------------------------------------------- + + word = pci_read_config16(dev, 0x50); + /* Ensure prefetch is disabled */ + word &= ~((1 << 15) | (1 << 13)); + if (conf->ide1_enable) { + /* Enable secondary ide interface */ + word |= (1<<0); + printk_debug("IDE1 \t"); + } + if (conf->ide0_enable) { + /* Enable primary ide interface */ + word |= (1<<1); + printk_debug("IDE0\n"); + } + + word |= (1<<12); + word |= (1<<14); + + pci_write_config16(dev, 0x50, word); + + + byte = 0x20 ; // Latency: 64-->32 + pci_write_config8(dev, 0xd, byte); + + dword = pci_read_config32(dev, 0xf8); + dword |= 12; + pci_write_config32(dev, 0xf8, dword); +#if CONFIG_PCI_ROM_RUN == 1 + pci_dev_init(dev); +#endif + +} + +static void lpci_set_subsystem(device_t dev, unsigned vendor, unsigned device) +{ + pci_write_config32(dev, 0x40, + ((device & 0xffff) << 16) | (vendor & 0xffff)); +} +static struct pci_operations lops_pci = { + .set_subsystem = lpci_set_subsystem, +}; + +static struct device_operations ide_ops = { + .read_resources = pci_dev_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_dev_enable_resources, + .init = ide_init, + .scan_bus = 0, +// .enable = sis966_enable, + .ops_pci = &lops_pci, +}; + +static struct pci_driver ide_driver __pci_driver = { + .ops = &ide_ops, + .vendor = PCI_VENDOR_ID_SIS, + .device = PCI_DEVICE_ID_SIS_SIS966_IDE, +}; + diff --git a/src/southbridge/sis/sis966/sis966_lpc.c b/src/southbridge/sis/sis966/sis966_lpc.c new file mode 100644 index 0000000000..efb7b2e151 --- /dev/null +++ b/src/southbridge/sis/sis966/sis966_lpc.c @@ -0,0 +1,451 @@ +/* + * This file is part of the LinuxBIOS project. + * + * Copyright (C) 2003 Linux Networx + * Copyright (C) 2003 SuSE Linux AG + * Copyright (C) 2004 Tyan Computer + * Written by Yinghai Lu for Tyan Computer. + * Copyright (C) 2006,2007 AMD + * Written by Yinghai Lu for AMD. + * Copyright (C) 2007 Silicon Integrated Systems Corp. (SiS) + * Written by Morgan Tsai for SiS. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "sis966.h" +#include + +#define NMI_OFF 0 + +struct ioapicreg { + unsigned int reg; + unsigned int value_low, value_high; +}; + +static struct ioapicreg ioapicregvalues[] = { +#define ALL (0xff << 24) +#define NONE (0) +#define DISABLED (1 << 16) +#define ENABLED (0 << 16) +#define TRIGGER_EDGE (0 << 15) +#define TRIGGER_LEVEL (1 << 15) +#define POLARITY_HIGH (0 << 13) +#define POLARITY_LOW (1 << 13) +#define PHYSICAL_DEST (0 << 11) +#define LOGICAL_DEST (1 << 11) +#define ExtINT (7 << 8) +#define NMI (4 << 8) +#define SMI (2 << 8) +#define INT (1 << 8) + /* IO-APIC virtual wire mode configuration */ + /* mask, trigger, polarity, destination, delivery, vector */ + { 0, ENABLED | TRIGGER_EDGE | POLARITY_HIGH | PHYSICAL_DEST | ExtINT, NONE}, + { 1, DISABLED, NONE}, + { 2, DISABLED, NONE}, + { 3, DISABLED, NONE}, + { 4, DISABLED, NONE}, + { 5, DISABLED, NONE}, + { 6, DISABLED, NONE}, + { 7, DISABLED, NONE}, + { 8, DISABLED, NONE}, + { 9, DISABLED, NONE}, + { 10, DISABLED, NONE}, + { 11, DISABLED, NONE}, + { 12, DISABLED, NONE}, + { 13, DISABLED, NONE}, + { 14, DISABLED, NONE}, + { 15, DISABLED, NONE}, + { 16, DISABLED, NONE}, + { 17, DISABLED, NONE}, + { 18, DISABLED, NONE}, + { 19, DISABLED, NONE}, + { 20, DISABLED, NONE}, + { 21, DISABLED, NONE}, + { 22, DISABLED, NONE}, + { 23, DISABLED, NONE}, + /* Be careful and don't write past the end... */ +}; + +static void setup_ioapic(unsigned long ioapic_base) +{ + int i; + unsigned long value_low, value_high; +// unsigned long ioapic_base = 0xfec00000; + volatile unsigned long *l; + struct ioapicreg *a = ioapicregvalues; + + ioapicregvalues[0].value_high = lapicid()<<(56-32); + + l = (unsigned long *) ioapic_base; + + for (i = 0; i < sizeof(ioapicregvalues) / sizeof(ioapicregvalues[0]); + i++, a++) { + l[0] = (a->reg * 2) + 0x10; + l[4] = a->value_low; + value_low = l[4]; + l[0] = (a->reg *2) + 0x11; + l[4] = a->value_high; + value_high = l[4]; + if ((i==0) && (value_low == 0xffffffff)) { + printk_warning("IO APIC not responding.\n"); + return; + } + printk_spew("for IRQ, reg 0x%08x value 0x%08x 0x%08x\n", + a->reg, a->value_low, a->value_high); + } +} + +// 0x7a or e3 +#define PREVIOUS_POWER_STATE 0x7A + +#define MAINBOARD_POWER_OFF 0 +#define MAINBOARD_POWER_ON 1 +#define SLOW_CPU_OFF 0 +#define SLOW_CPU__ON 1 + +#ifndef MAINBOARD_POWER_ON_AFTER_POWER_FAIL +#define MAINBOARD_POWER_ON_AFTER_POWER_FAIL MAINBOARD_POWER_ON +#endif + +static void lpc_common_init(device_t dev) +{ + uint8_t byte; + uint32_t dword; + + /* IO APIC initialization */ + byte = pci_read_config8(dev, 0x74); + byte |= (1<<0); // enable APIC + pci_write_config8(dev, 0x74, byte); + dword = pci_read_config32(dev, PCI_BASE_ADDRESS_1); // 0x14 + + setup_ioapic(dword); + +} + +static void lpc_slave_init(device_t dev) +{ + lpc_common_init(dev); +} + +#if 0 +static void enable_hpet(struct device *dev) +{ + unsigned long hpet_address; + + pci_write_config32(dev,0x44, 0xfed00001); + hpet_address=pci_read_config32(dev,0x44)& 0xfffffffe; + printk_debug("enabling HPET @0x%x\n", hpet_address); +} +#endif + +static void lpc_usb_legacy_init(device_t dev) +{ + uint16_t acpi_base; + + acpi_base = (pci_read_config8(dev,0x75) << 8); + //printk_debug("ACPI Base Addr=0x%4.4x\n",acpi_base); + + //printk_debug("acpi_base + 0xbb=%.2x\n", inb(acpi_base + 0xbb)); + //printk_debug("acpi_base + 0xba=%.2x\n", inb(acpi_base + 0xba)); + + outb(inb(acpi_base + 0xbb) |0x80, acpi_base + 0xbb); + outb(inb(acpi_base + 0xba) |0x80, acpi_base + 0xba); + + //printk_debug("acpi_base + 0xbb=%.2x\n", inb(acpi_base + 0xbb)); + //printk_debug("acpi_base + 0xba=%.2x\n", inb(acpi_base + 0xba)); + + return; +} + +static void lpc_init(device_t dev) +{ + uint8_t byte; + uint8_t byte_old; + int on; + int nmi_option; + + printk_debug("lpc_init -------->\n"); + init_pc_keyboard(0x60, 0x64, 0); + +#if 0 + { + int i; + printk_debug("LPC PCI config \n"); + for(i=0;i<0xFF;i+=4) + { + if((i%16)==0) + { + print_debug("\r\n"); + print_debug_hex8(i); + print_debug(" ");} + print_debug_hex32(pci_read_config32(dev,i)); + print_debug(" "); + } + print_debug("\r\n"); + } +#endif + printk_debug("lpc_init <--------\n"); + lpc_usb_legacy_init(dev); + return; + + printk_debug("lpc_init\r\n"); + lpc_common_init(dev); + printk_debug("lpc_init2\r\n"); + + +#if 0 + /* posted memory write enable */ + byte = pci_read_config8(dev, 0x46); + pci_write_config8(dev, 0x46, byte | (1<<0)); + +#endif + /* power after power fail */ + +#if 1 + on = MAINBOARD_POWER_ON_AFTER_POWER_FAIL; + get_option(&on, "power_on_after_fail"); + byte = pci_read_config8(dev, PREVIOUS_POWER_STATE); + byte &= ~0x40; + if (!on) { + byte |= 0x40; + } + pci_write_config8(dev, PREVIOUS_POWER_STATE, byte); + printk_info("set power %s after power fail\n", on?"on":"off"); +#endif + /* Throttle the CPU speed down for testing */ + on = SLOW_CPU_OFF; + get_option(&on, "slow_cpu"); + if(on) { + uint16_t pm10_bar; + uint32_t dword; + pm10_bar = (pci_read_config16(dev, 0x60)&0xff00); + outl(((on<<1)+0x10) ,(pm10_bar + 0x10)); + dword = inl(pm10_bar + 0x10); + on = 8-on; + printk_debug("Throttling CPU %2d.%1.1d percent.\n", + (on*12)+(on>>1),(on&1)*5); + } + +#if 0 +// default is enabled + /* Enable Port 92 fast reset */ + byte = pci_read_config8(dev, 0xe8); + byte |= ~(1 << 3); + pci_write_config8(dev, 0xe8, byte); +#endif + + /* Enable Error reporting */ + /* Set up sync flood detected */ + byte = pci_read_config8(dev, 0x47); + byte |= (1 << 1); + pci_write_config8(dev, 0x47, byte); + + /* Set up NMI on errors */ + byte = inb(0x70); // RTC70 + byte_old = byte; + nmi_option = NMI_OFF; + get_option(&nmi_option, "nmi"); + if (nmi_option) { + byte &= ~(1 << 7); /* set NMI */ + } else { + byte |= ( 1 << 7); // Can not mask NMI from PCI-E and NMI_NOW + } + if( byte != byte_old) { + outb(0x70, byte); + } + + /* Initialize the real time clock */ + rtc_init(0); + + /* Initialize isa dma */ + isa_dma_init(); + + /* Initialize the High Precision Event Timers */ +// enable_hpet(dev); + +} + +static void sis966_lpc_read_resources(device_t dev) +{ + struct resource *res; + unsigned long index; + + /* Get the normal pci resources of this device */ + pci_dev_read_resources(dev); // We got one for APIC, or one more for TRAP + + /* Add an extra subtractive resource for both memory and I/O */ + res = new_resource(dev, IOINDEX_SUBTRACTIVE(0, 0)); + res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED; + + res = new_resource(dev, IOINDEX_SUBTRACTIVE(1, 0)); + res->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED; + +} + +/** + * @brief Enable resources for children devices + * + * @param dev the device whos children's resources are to be enabled + * + * This function is call by the global enable_resources() indirectly via the + * device_operation::enable_resources() method of devices. + * + * Indirect mutual recursion: + * enable_childrens_resources() -> enable_resources() + * enable_resources() -> device_operation::enable_resources() + * device_operation::enable_resources() -> enable_children_resources() + */ +static void sis966_lpc_enable_childrens_resources(device_t dev) +{ + unsigned link; + uint32_t reg, reg_var[4]; + int i; + int var_num = 0; + + reg = pci_read_config32(dev, 0xa0); + + for (link = 0; link < dev->links; link++) { + device_t child; + for (child = dev->link[link].children; child; child = child->sibling) { + enable_resources(child); + if(child->have_resources && (child->path.type == DEVICE_PATH_PNP)) { + for(i=0;iresources;i++) { + struct resource *res; + unsigned long base, end; // don't need long long + res = &child->resource[i]; + if(!(res->flags & IORESOURCE_IO)) continue; + base = res->base; + end = resource_end(res); + printk_debug("sis966 lpc decode:%s, base=0x%08x, end=0x%08x\n",dev_path(child),base, end); + switch(base) { + case 0x3f8: // COM1 + reg |= (1<<0); break; + case 0x2f8: // COM2 + reg |= (1<<1); break; + case 0x378: // Parallal 1 + reg |= (1<<24); break; + case 0x3f0: // FD0 + reg |= (1<<20); break; + case 0x220: // Aduio 0 + reg |= (1<<8); break; + case 0x300: // Midi 0 + reg |= (1<<12); break; + } + if( (base == 0x290) || (base >= 0x400)) { + if(var_num>=4) continue; // only 4 var ; compact them ? + reg |= (1<<(28+var_num)); + reg_var[var_num++] = (base & 0xffff)|((end & 0xffff)<<16); + } + } + } + } + } + pci_write_config32(dev, 0xa0, reg); + for(i=0;i for Tyan Computer. + * Copyright (C) 2006,2007 AMD + * Written by Yinghai Lu for AMD. + * Copyright (C) 2007 Silicon Integrated Systems Corp. (SiS) + * Written by Morgan Tsai for SiS. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "sis966.h" + + +uint8_t SiS_SiS191_init[6][3]={ +{0x04, 0xFF, 0x07}, +{0x2C, 0xFF, 0x39}, +{0x2D, 0xFF, 0x10}, +{0x2E, 0xFF, 0x91}, +{0x2F, 0xFF, 0x01}, +{0x00, 0x00, 0x00} //End of table +}; + +#if 1 +#define StatusReg 0x1 +#define SMI_READ 0x0 +#define SMI_REQUEST 0x10 +#define TRUE 1 +#define FALSE 0 + +uint16_t MacAddr[3]; + + +void writeApcByte(int addr, uint8_t value) +{ + outb(addr,0x78); + outb(value,0x79); +} +uint8_t readApcByte(int addr) +{ + uint8_t value; + outb(addr,0x78); + value=inb(0x79); + return(value); +} + +static void readApcMacAddr(void) +{ + uint8_t i; + +// enable APC in south bridge sis966 D2F0 + + outl(0x80001048,0xcf8); + outl((inl(0xcfc) & 0xfffffffd),0xcfc ); // enable IO78/79h for APC Index/Data + + printk_debug("MAC addr in APC = "); + for(i = 0x9 ; i <=0xe ; i++) + { + printk_debug("%2.2x",readApcByte(i)); + } + printk_debug("\n"); + + /* Set APC Reload */ + writeApcByte(0x7,readApcByte(0x7)&0xf7); + writeApcByte(0x7,readApcByte(0x7)|0x0a); + + /* disable APC in south bridge */ + outl(0x80001048,0xcf8); + outl(inl(0xcfc)&0xffffffbf,0xcfc); +} + +static void set_apc(struct device *dev) +{ + uint32_t tmp; + uint16_t addr; + uint32_t idx; + uint16_t i; + uint8_t bTmp; + + /* enable APC in south bridge sis966 D2F0 */ + outl(0x80001048,0xcf8); + outl((inl(0xcfc) & 0xfffffffd),0xcfc ); // enable IO78/79h for APC Index/Data + + for(i = 0 ; i <3; i++) + { + addr=0x9+2*i; + writeApcByte(addr,(uint8_t)(MacAddr[i]&0xFF)); + writeApcByte(addr+1L,(uint8_t)((MacAddr[i]>>8)&0xFF)); + // printf("%x - ",readMacAddrByte(0x59+i)); + } + + /* Set APC Reload */ + writeApcByte(0x7,readApcByte(0x7)&0xf7); + writeApcByte(0x7,readApcByte(0x7)|0x0a); + + /* disable APC in south bridge */ + outl(0x80001048,0xcf8); + outl(inl(0xcfc)&0xffffffbf,0xcfc); + + // CFG reg0x73 bit=1, tell driver MAC Address load to APC + bTmp = pci_read_config8(dev, 0x73); + bTmp|=0x1; + pci_write_config8(dev, 0x73, bTmp); +} + +//----------------------------------------------------------------------------- +// Procedure: ReadEEprom +// +// Description: This routine serially reads one word out of the EEPROM. +// +// Arguments: +// Reg - EEPROM word to read. +// +// Returns: +// Contents of EEPROM word (Reg). +//----------------------------------------------------------------------------- +#define LoopNum 200 +static unsigned long ReadEEprom( struct device *dev, uint32_t base, uint32_t Reg) +{ + uint16_t data; + uint32_t i; + uint32_t ulValue; + + + ulValue = (0x80 | (0x2 << 8) | (Reg << 10)); //BIT_7 + + writel( ulValue,base+0x3c); + + mdelay(10); + + for(i=0 ; i <= LoopNum; i++) + { + ulValue=readl(base+0x3c); + + if(!(ulValue & 0x0080)) //BIT_7 + break; + + mdelay(100); + } + + mdelay(50); + + if(i==LoopNum) data=0x10000; + else{ + ulValue=readl(base+0x3c); + data = (uint16_t)((ulValue & 0xffff0000) >> 16); + } + + return data; +} + +static int phy_read(uint32_t base, unsigned phy_addr, unsigned phy_reg) +{ + uint32_t ulValue; + unsigned loop = 0x100; + uint32_t Read_Cmd; + uint16_t usData; + + uint16_t tmp; + + + Read_Cmd = ((phy_reg << 11) | + (phy_addr << 6) | + SMI_READ | + SMI_REQUEST); + + // SmiMgtInterface Reg is the SMI management interface register(offset 44h) of MAC + writel( Read_Cmd,base+0x44); + //outl( Read_Cmd,tmp+0x44); + + // Polling SMI_REQ bit to be deasserted indicated read command completed + do + { + // Wait 20 usec before checking status + //StallAndWait(20); + mdelay(20); + ulValue = readl(base+0x44); + //ulValue = inl(tmp+0x44); + } while((ulValue & SMI_REQUEST) != 0); + //printk_debug("base %x cmd %lx ret val %lx\n", tmp,Read_Cmd,ulValue); + usData=(ulValue>>16); + + + + return usData; + +} + +// Detect a valid PHY +// If there exist a valid PHY then return TRUE, else return FALSE +static int phy_detect(uint32_t base,uint16_t *PhyAddr) //BOOL PHY_Detect() +{ + int bFoundPhy = FALSE; + uint32_t Read_Cmd; + uint16_t usData; + int PhyAddress = 0; + + + // Scan all PHY address(0 ~ 31) to find a valid PHY + for(PhyAddress = 0; PhyAddress < 32; PhyAddress++) + { + usData=phy_read(base,PhyAddress,StatusReg); // Status register is a PHY's register(offset 01h) + + // Found a valid PHY + + if((usData != 0x0) && (usData != 0xffff)) + { + bFoundPhy = TRUE; + break; + } + } +// printk_debug(" PHY_Addr=%x\n",PhyAddress); + + //usData=phy_read(base,PhyAddress,0x0); + //printk_debug("PHY=%x\n",usData); + + if(!bFoundPhy) + { + printk_debug("PHY not found !!!! \n"); + // DisableMac(); + } + + *PhyAddr=PhyAddress; + + return bFoundPhy; +} + + +static void nic_init(struct device *dev) +{ + uint32_t dword, old; + uint32_t mac_h, mac_l; + int eeprom_valid = 0; + int val; + uint16_t PhyAddr; + struct southbridge_sis_sis966_config *conf; + + static uint32_t nic_index = 0; + + uint32_t base; + struct resource *res; + uint32_t reg; + + +printk_debug("SIS NIC init-------->\r\n"); + + +//-------------- enable NIC (SiS19x) ------------------------- +{ + uint8_t temp8; + int i=0; + while(SiS_SiS191_init[i][0] != 0) + { temp8 = pci_read_config8(dev, SiS_SiS191_init[i][0]); + temp8 &= SiS_SiS191_init[i][1]; + temp8 |= SiS_SiS191_init[i][2]; + pci_write_config8(dev, SiS_SiS191_init[i][0], temp8); + i++; + }; +} +//----------------------------------------------------------- + + + + +{ +unsigned long i; +unsigned long ulValue; + +#if 0 +for(i=0;i<0xFF;i+=4) +{ if((i%16)==0) + {print_debug("\r\n");print_debug_hex8(i);print_debug(" ");} + print_debug_hex32(pci_read_config32(dev,i)); + print_debug(" "); +} +print_debug("\r\n"); +#endif + res = find_resource(dev, 0x10); + + if(!res) return; + + base = res->base; +printk_debug("NIC base address %lx\n",base); + if(!(val=phy_detect(base,&PhyAddr))) + { + printk_debug("PHY detect fail !!!!\r\n"); + return; + } + +#if 0 +//------------ show op registers ---------------------- +{ +//device_t dev; +int i; +//dev = pci_locate_device(PCI_ID(0x1039, 0x5513), 0); +printk_debug("NIC OP Registers \n"); +for(i=0;i<0xFF;i+=4) +{ if((i%16)==0) + {print_debug("\r\n");print_debug_hex8(i);print_debug(" ");} + print_debug_hex32(readl(base+i)); + print_debug(" "); +} + +} + +//---------------------------------------------------- +#endif + + ulValue=readl(base + 0x38L); // check EEPROM existing + + if((ulValue & 0x0002)) + { + + // read MAC address from EEPROM at first + + // if that is valid we will use that + + printk_debug("EEPROM contents %x \n",ReadEEprom( dev, base, 0LL)); + for(i=0;i<3;i++) { + //status = smbus_read_byte(dev_eeprom, i); + ulValue=ReadEEprom( dev, base, i+3L); + if (ulValue ==0x10000) break; // error + + MacAddr[i] =ulValue & 0xFFFF; + + } + + }else{ + // read MAC address from firmware + printk_debug("EEPROM invalid!!\nReg 0x38h=%.8lx \n",ulValue); + MacAddr[0]=readw(0xffffffc0); // mac address store at here + MacAddr[1]=readw(0xffffffc2); + MacAddr[2]=readw(0xffffffc4); + } + + +#if 0 +// read MAC address from EEPROM at first +printk_debug("MAC address in firmware trap \n"); + for( i=0;i<3;i++) + printk_debug(" %4x\n",MacAddr[i]); + printk_debug("\n"); +#endif + +set_apc(dev); + +readApcMacAddr(); + +#if 0 +{ +//device_t dev; +int i; +//dev = pci_locate_device(PCI_ID(0x1039, 0x5513), 0); +printk_debug("NIC PCI config \n"); +for(i=0;i<0xFF;i+=4) +{ if((i%16)==0) + {print_debug("\r\n");print_debug_hex8(i);print_debug(" ");} + print_debug_hex32(pci_read_config32(dev,i)); + print_debug(" "); +} + +} +#endif + +} + +printk_debug("nic_init<--------\r\n"); +return; + +#define RegStationMgtInf 0x44 +#define PHY_RGMII 0x10000000 + + writel(PHY_RGMII, base + RegStationMgtInf); + conf = dev->chip_info; + + if(conf->mac_eeprom_smbus != 0) { +// read MAC address from EEPROM at first + + struct device *dev_eeprom; + dev_eeprom = dev_find_slot_on_smbus(conf->mac_eeprom_smbus, conf->mac_eeprom_addr); + + if(dev_eeprom) { + // if that is valid we will use that + unsigned char dat[6]; + int status; + int i; + for(i=0;i<6;i++) { + status = smbus_read_byte(dev_eeprom, i); + if(status < 0) break; + dat[i] = status & 0xff; + } + if(status >= 0) { + mac_l = 0; + for(i=3;i>=0;i--) { + mac_l <<= 8; + mac_l += dat[i]; + } + if(mac_l != 0xffffffff) { + mac_l += nic_index; + mac_h = 0; + for(i=5;i>=4;i--) { + mac_h <<= 8; + mac_h += dat[i]; + } + eeprom_valid = 1; + } + } + } + } +// if that is invalid we will read that from romstrap + if(!eeprom_valid) { + unsigned long mac_pos; + mac_pos = 0xffffffd0; // refer to romstrap.inc and romstrap.lds + mac_l = readl(mac_pos) + nic_index; // overflow? + mac_h = readl(mac_pos + 4); + + } +#if 1 +// set that into NIC MMIO +#define NvRegMacAddrA 0xA8 +#define NvRegMacAddrB 0xAC + writel(mac_l, base + NvRegMacAddrA); + writel(mac_h, base + NvRegMacAddrB); +#else +// set that into NIC + pci_write_config32(dev, 0xa8, mac_l); + pci_write_config32(dev, 0xac, mac_h); +#endif + + nic_index++; + +#if CONFIG_PCI_ROM_RUN == 1 + pci_dev_init(dev);// it will init option rom +#endif + +} + + + +#else // orginal code + +tatic int phy_read(uint8_t *base, unsigned phy_addr, unsigned phy_reg) +{ + uint32_t dword; + unsigned loop = 0x100; + writel(0x8000, base+0x190); //Clear MDIO lock bit + mdelay(1); + dword = readl(base+0x190); + if(dword & (1<<15)) return -1; + + writel(1, base+0x180); + writel((phy_addr<<5) | (phy_reg),base + 0x190); + do{ + dword = readl(base + 0x190); + if(--loop==0) return -4; + } while ((dword & (1<<15)) ); + + dword = readl(base + 0x180); + if(dword & 1) return -3; + + dword = readl(base + 0x194); + + return dword; + +} + +static int phy_detect(uint8_t *base) +{ + uint32_t dword; + int i; + int val; + unsigned id; + dword = readl(base+0x188); + dword &= ~(1<<20); + writel(dword, base+0x188); + + phy_read(base, 0, 1); + + for(i=1; i<=32; i++) { + int phyaddr = i & 0x1f; + val = phy_read(base, phyaddr, 1); + if(val<0) continue; + if((val & 0xffff) == 0xfffff) continue; + if((val & 0xffff) == 0) continue; + if(!(val & 1)) { + break; // Ethernet PHY + } + val = phy_read(base, phyaddr, 3); + if (val < 0 || val == 0xffff) continue; + id = val & 0xfc00; + val = phy_read(base, phyaddr, 2); + if (val < 0 || val == 0xffff) continue; + id |= ((val & 0xffff)<<16); + printk_debug("SIS966 MAC PHY ID 0x%08x PHY ADDR %d\n", id, i); +// if((id == 0xe0180000) || (id==0x0032cc00)) + break; + } + + if(i>32) { + printk_debug("SIS966 MAC PHY not found\n"); + } + +} +static void nic_init(struct device *dev) +{ + uint32_t dword, old; + uint32_t mac_h, mac_l; + int eeprom_valid = 0; + struct southbridge_sis_sis966_config *conf; + + static uint32_t nic_index = 0; + + uint8_t *base; + struct resource *res; + + res = find_resource(dev, 0x10); + + if(!res) return; + + base = res->base; + + phy_detect(base); + +#define NvRegPhyInterface 0xC0 +#define PHY_RGMII 0x10000000 + + writel(PHY_RGMII, base + NvRegPhyInterface); + + conf = dev->chip_info; + + if(conf->mac_eeprom_smbus != 0) { +// read MAC address from EEPROM at first + struct device *dev_eeprom; + dev_eeprom = dev_find_slot_on_smbus(conf->mac_eeprom_smbus, conf->mac_eeprom_addr); + + if(dev_eeprom) { + // if that is valid we will use that + unsigned char dat[6]; + int status; + int i; + for(i=0;i<6;i++) { + status = smbus_read_byte(dev_eeprom, i); + if(status < 0) break; + dat[i] = status & 0xff; + } + if(status >= 0) { + mac_l = 0; + for(i=3;i>=0;i--) { + mac_l <<= 8; + mac_l += dat[i]; + } + if(mac_l != 0xffffffff) { + mac_l += nic_index; + mac_h = 0; + for(i=5;i>=4;i--) { + mac_h <<= 8; + mac_h += dat[i]; + } + eeprom_valid = 1; + } + } + } + } +// if that is invalid we will read that from romstrap + if(!eeprom_valid) { + unsigned long mac_pos; + mac_pos = 0xffffffd0; // refer to romstrap.inc and romstrap.lds + mac_l = readl(mac_pos) + nic_index; // overflow? + mac_h = readl(mac_pos + 4); + + } +#if 1 +// set that into NIC MMIO +#define NvRegMacAddrA 0xA8 +#define NvRegMacAddrB 0xAC + writel(mac_l, base + NvRegMacAddrA); + writel(mac_h, base + NvRegMacAddrB); +#else +// set that into NIC + pci_write_config32(dev, 0xa8, mac_l); + pci_write_config32(dev, 0xac, mac_h); +#endif + + nic_index++; + +#if CONFIG_PCI_ROM_RUN == 1 + pci_dev_init(dev);// it will init option rom +#endif + +} + +#endif +static void lpci_set_subsystem(device_t dev, unsigned vendor, unsigned device) +{ + pci_write_config32(dev, 0x40, + ((device & 0xffff) << 16) | (vendor & 0xffff)); +} + +static struct pci_operations lops_pci = { + .set_subsystem = lpci_set_subsystem, +}; + +static struct device_operations nic_ops = { + .read_resources = pci_dev_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_dev_enable_resources, + .init = nic_init, + .scan_bus = 0, +// .enable = sis966_enable, + .ops_pci = &lops_pci, +}; +static struct pci_driver nic_driver __pci_driver = { + .ops = &nic_ops, + .vendor = PCI_VENDOR_ID_SIS, + .device = PCI_DEVICE_ID_SIS_SIS966_NIC1, +}; +static struct pci_driver nic_bridge_driver __pci_driver = { + .ops = &nic_ops, + .vendor = PCI_VENDOR_ID_SIS, + .device = PCI_DEVICE_ID_SIS_SIS966_NIC_BRIDGE, +}; diff --git a/src/southbridge/sis/sis966/sis966_pci.c b/src/southbridge/sis/sis966/sis966_pci.c new file mode 100644 index 0000000000..db1d986a08 --- /dev/null +++ b/src/southbridge/sis/sis966/sis966_pci.c @@ -0,0 +1,109 @@ +/* + * This file is part of the LinuxBIOS project. + * + * Copyright (C) 2004 Tyan Computer + * Written by Yinghai Lu for Tyan Computer. + * Copyright (C) 2006,2007 AMD + * Written by Yinghai Lu for AMD. + * Copyright (C) 2007 Silicon Integrated Systems Corp. (SiS) + * Written by Morgan Tsai for SiS. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include "sis966.h" + +static void pci_init(struct device *dev) +{ + + uint32_t dword; + uint16_t word; +#if CONFIG_PCI_64BIT_PREF_MEM == 1 + device_t pci_domain_dev; + struct resource *mem1, *mem2; +#endif + + /* System error enable */ + dword = pci_read_config32(dev, 0x04); + dword |= (1<<8); /* System error enable */ + dword |= (1<<30); /* Clear possible errors */ + pci_write_config32(dev, 0x04, dword); + +#if 1 + //only need (a01,xx] + word = pci_read_config16(dev, 0x48); + word |= (1<<0); /* MRL2MRM */ + word |= (1<<2); /* MR2MRM */ + pci_write_config16(dev, 0x48, word); +#endif + +#if 1 + dword = pci_read_config32(dev, 0x4c); + dword |= 0x00440000; /*TABORT_SER_ENABLE Park Last Enable.*/ + pci_write_config32(dev, 0x4c, dword); +#endif + +#if CONFIG_PCI_64BIT_PREF_MEM == 1 + pci_domain_dev = dev->bus->dev; + while(pci_domain_dev) { + if(pci_domain_dev->path.type == DEVICE_PATH_PCI_DOMAIN) break; + pci_domain_dev = pci_domain_dev->bus->dev; + } + + if(!pci_domain_dev) return; // impossiable + mem1 = find_resource(pci_domain_dev, 1); // prefmem, it could be 64bit + mem2 = find_resource(pci_domain_dev, 2); // mem + if(mem1->base > mem2->base) { + dword = mem2->base & (0xffff0000UL); + printk_debug("PCI DOMAIN mem2 base = 0x%010Lx\n", mem2->base); + } else { + dword = mem1->base & (0xffff0000UL); + printk_debug("PCI DOMAIN mem1 (prefmem) base = 0x%010Lx\n", mem1->base); + } +#else + dword = dev_root.resource[1].base & (0xffff0000UL); + printk_debug("dev_root mem base = 0x%010Lx\n", dev_root.resource[1].base); +#endif + printk_debug("[0x50] <-- 0x%08x\n", dword); + pci_write_config32(dev, 0x50, dword); //TOM + +} + +static struct pci_operations lops_pci = { + .set_subsystem = 0, +}; + +static struct device_operations pci_ops = { + .read_resources = pci_bus_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_bus_enable_resources, + .init = pci_init, + .scan_bus = pci_scan_bridge, +// .enable = sis966_enable, + .reset_bus = pci_bus_reset, + .ops_pci = &lops_pci, +}; + +static struct pci_driver pci_driver __pci_driver = { + .ops = &pci_ops, + .vendor = PCI_VENDOR_ID_SIS, + .device = PCI_DEVICE_ID_SIS_SIS966_PCI, +}; + diff --git a/src/southbridge/sis/sis966/sis966_pcie.c b/src/southbridge/sis/sis966/sis966_pcie.c new file mode 100644 index 0000000000..3984554378 --- /dev/null +++ b/src/southbridge/sis/sis966/sis966_pcie.c @@ -0,0 +1,86 @@ +/* + * This file is part of the LinuxBIOS project. + * + * Copyright (C) 2004 Tyan Computer + * Written by Yinghai Lu for Tyan Computer. + * Copyright (C) 2006,2007 AMD + * Written by Yinghai Lu for AMD. + * Copyright (C) 2007 Silicon Integrated Systems Corp. (SiS) + * Written by Morgan Tsai for SiS. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include "sis966.h" + +static void pcie_init(struct device *dev) +{ + + /* Enable pci error detecting */ + uint32_t dword; + + /* System error enable */ + dword = pci_read_config32(dev, 0x04); + dword |= (1<<8); /* System error enable */ + dword |= (1<<30); /* Clear possible errors */ + pci_write_config32(dev, 0x04, dword); + +} + +static struct pci_operations lops_pci = { + .set_subsystem = 0, +}; + +static struct device_operations pcie_ops = { + .read_resources = pci_bus_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_bus_enable_resources, + .init = pcie_init, + .scan_bus = pci_scan_bridge, +// .enable = sis966_enable, + .ops_pci = &lops_pci, +}; + +static struct pci_driver pciebc_driver __pci_driver = { + .ops = &pcie_ops, + .vendor = PCI_VENDOR_ID_SIS, + .device = PCI_DEVICE_ID_SIS_SIS966_PCIE_B_C, +}; +static struct pci_driver pciee_driver __pci_driver = { + .ops = &pcie_ops, + .vendor = PCI_VENDOR_ID_SIS, + .device = PCI_DEVICE_ID_SIS_SIS966_PCIE_E, +}; +static struct pci_driver pciea_driver __pci_driver = { + .ops = &pcie_ops, + .vendor = PCI_VENDOR_ID_SIS, + .device = PCI_DEVICE_ID_SIS_SIS966_PCIE_A, +}; +static struct pci_driver pcief_driver __pci_driver = { + .ops = &pcie_ops, + .vendor = PCI_VENDOR_ID_SIS, + .device = PCI_DEVICE_ID_SIS_SIS966_PCIE_F, +}; +static struct pci_driver pcied_driver __pci_driver = { + .ops = &pcie_ops, + .vendor = PCI_VENDOR_ID_SIS, + .device = PCI_DEVICE_ID_SIS_SIS966_PCIE_D, +}; + diff --git a/src/southbridge/sis/sis966/sis966_reset.c b/src/southbridge/sis/sis966/sis966_reset.c new file mode 100644 index 0000000000..3c08e79615 --- /dev/null +++ b/src/southbridge/sis/sis966/sis966_reset.c @@ -0,0 +1,59 @@ +/* + * This file is part of the LinuxBIOS project. + * + * Copyright (C) 2004 Tyan Computer + * Written by Yinghai Lu for Tyan Computer. + * Copyright (C) 2006,2007 AMD + * Written by Yinghai Lu for AMD. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#define PCI_DEV(BUS, DEV, FN) ( \ + (((BUS) & 0xFFF) << 20) | \ + (((DEV) & 0x1F) << 15) | \ + (((FN) & 0x7) << 12)) + +typedef unsigned device_t; + +static void pci_write_config32(device_t dev, unsigned where, unsigned value) +{ + unsigned addr; + addr = (dev>>4) | where; + outl(0x80000000 | (addr & ~3), 0xCF8); + outl(value, 0xCFC); +} + +static unsigned pci_read_config32(device_t dev, unsigned where) +{ + unsigned addr; + addr = (dev>>4) | where; + outl(0x80000000 | (addr & ~3), 0xCF8); + return inl(0xCFC); +} + +#include "../../../northbridge/amd/amdk8/reset_test.c" + +void hard_reset(void) +{ + set_bios_reset(); + /* Try rebooting through port 0xcf9 */ + /* Actually it is not a real hard_reset --- it only reset coherent link table, but not reset link freq and width */ + outb((0 <<3)|(0<<2)|(1<<1), 0xcf9); + outb((0 <<3)|(1<<2)|(1<<1), 0xcf9); +} + diff --git a/src/southbridge/sis/sis966/sis966_sata.c b/src/southbridge/sis/sis966/sis966_sata.c new file mode 100644 index 0000000000..c495aa5e45 --- /dev/null +++ b/src/southbridge/sis/sis966/sis966_sata.c @@ -0,0 +1,301 @@ +/* + * This file is part of the LinuxBIOS project. + * + * Copyright (C) 2004 Tyan Computer + * Written by Yinghai Lu for Tyan Computer. + * Copyright (C) 2006,2007 AMD + * Written by Yinghai Lu for AMD. + * Copyright (C) 2007 Silicon Integrated Systems Corp. (SiS) + * Written by Morgan Tsai for SiS. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include +#include "sis966.h" +#include + +#if 1 +uint8_t SiS_SiS1183_init[68][3]={ +{0x04, 0x00, 0x05}, +{0x09, 0x00, 0x05}, +{0x2C, 0x00, 0x39}, +{0x2D, 0x00, 0x10}, +{0x2E, 0x00, 0x83}, +{0x2F, 0x00, 0x11}, +{0x90, 0x00, 0x40}, +{0x91, 0x00, 0x00}, // set mode +{0x50, 0x00, 0xA2}, +{0x52, 0x00, 0xA2}, +{0x55, 0x00, 0x96}, +{0x52, 0x00, 0xA2}, +{0x55, 0xF7, 0x00}, +{0x56, 0x00, 0xC0}, +{0x57, 0x00, 0x14}, +{0x67, 0x00, 0x28}, +{0x81, 0x00, 0xB3}, +{0x82, 0x00, 0x72}, +{0x83, 0x00, 0x40}, +{0x85, 0x00, 0xB3}, +{0x86, 0x00, 0x72}, +{0x87, 0x00, 0x40}, +{0x88, 0x00, 0xDE}, // after set mode +{0x89, 0x00, 0xB3}, +{0x8A, 0x00, 0x72}, +{0x8B, 0x00, 0x40}, +{0x8C, 0x00, 0xDE}, +{0x8D, 0x00, 0xB3}, +{0x8E, 0x00, 0x92}, +{0x8F, 0x00, 0x40}, +{0x93, 0x00, 0x00}, +{0x94, 0x00, 0x80}, +{0x95, 0x00, 0x08}, +{0x96, 0x00, 0x80}, +{0x97, 0x00, 0x08}, +{0x9C, 0x00, 0x80}, +{0x9D, 0x00, 0x08}, +{0x9E, 0x00, 0x80}, +{0x9F, 0x00, 0x08}, +{0xA0, 0x00, 0x15}, +{0xA1, 0x00, 0x15}, +{0xA2, 0x00, 0x15}, +{0xA3, 0x00, 0x15}, + + +{0xD8, 0xFE, 0x01}, // Com reset +{0xC8, 0xFE, 0x01}, +{0xE8, 0xFE, 0x01}, +{0xF8, 0xFE, 0x01}, + +{0xD8, 0xFE, 0x00}, // Com reset +{0xC8, 0xFE, 0x00}, +{0xE8, 0xFE, 0x00}, +{0xF8, 0xFE, 0x00}, + + +{0xC4, 0xFF, 0xFF}, // Clear status +{0xC5, 0xFF, 0xFF}, +{0xC6, 0xFF, 0xFF}, +{0xC7, 0xFF, 0xFF}, +{0xD4, 0xFF, 0xFF}, +{0xD5, 0xFF, 0xFF}, +{0xD6, 0xFF, 0xFF}, +{0xD7, 0xFF, 0xFF}, +{0xE4, 0xFF, 0xFF}, // Clear status +{0xE5, 0xFF, 0xFF}, +{0xE6, 0xFF, 0xFF}, +{0xE7, 0xFF, 0xFF}, +{0xF4, 0xFF, 0xFF}, +{0xF5, 0xFF, 0xFF}, +{0xF6, 0xFF, 0xFF}, +{0xF7, 0xFF, 0xFF}, + +{0x00, 0x00, 0x00} //End of table +}; + + +#else +uint8_t SiS_SiS1183_init[5][3]={ + +{0xD8, 0xFE, 0x01}, // Com reset +{0xC8, 0xFE, 0x01}, +{0xE8, 0xFE, 0x01}, +{0xF8, 0xFE, 0x01}, + +{0x00, 0x00, 0x00} +}; //End of table + +uint8_t SiS_SiS1183_init2[21][3]={ +{0xD8, 0xFE, 0x00}, +{0xC8, 0xFE, 0x00}, +{0xE8, 0xFE, 0x00}, +{0xF8, 0xFE, 0x00}, + + +{0xC4, 0xFF, 0xFF}, // Clear status +{0xC5, 0xFF, 0xFF}, +{0xC6, 0xFF, 0xFF}, +{0xC7, 0xFF, 0xFF}, +{0xD4, 0xFF, 0xFF}, +{0xD5, 0xFF, 0xFF}, +{0xD6, 0xFF, 0xFF}, +{0xD7, 0xFF, 0xFF}, +{0xE4, 0xFF, 0xFF}, // Clear status +{0xE5, 0xFF, 0xFF}, +{0xE6, 0xFF, 0xFF}, +{0xE7, 0xFF, 0xFF}, +{0xF4, 0xFF, 0xFF}, +{0xF5, 0xFF, 0xFF}, +{0xF6, 0xFF, 0xFF}, +{0xF7, 0xFF, 0xFF}, + + +{0x00, 0x00, 0x00} //End of table +}; +#endif + + + +static void sata_init(struct device *dev) +{ + uint32_t dword; + struct southbridge_sis_sis966_config *conf; + + +struct resource *res; +uint16_t base; +uint8_t temp8; + + conf = dev->chip_info; +printk_debug("SATA(SiS1183)_init-------->\r\n"); + +#if 1 +//-------------- enable IDE (SiS5513) ------------------------- +{ + uint8_t temp8; + int i=0; + while(SiS_SiS1183_init[i][0] != 0) + { temp8 = pci_read_config8(dev, SiS_SiS1183_init[i][0]); + temp8 &= SiS_SiS1183_init[i][1]; + temp8 |= SiS_SiS1183_init[i][2]; + pci_write_config8(dev, SiS_SiS1183_init[i][0], temp8); + i++; + }; +} +/* +mdelay(5); +{ + uint8_t temp8; + int i=0; + while(SiS_SiS1183_init2[i][0] != 0) + { temp8 = pci_read_config8(dev, SiS_SiS1183_init2[i][0]); + temp8 &= SiS_SiS1183_init2[i][1]; + temp8 |= SiS_SiS1183_init2[i][2]; + pci_write_config8(dev, SiS_SiS1183_init2[i][0], temp8); + i++; + }; +} +*/ +//----------------------------------------------------------- +#endif + + +#if 0 + + dword = pci_read_config32(dev, 0x50); + /* Ensure prefetch is disabled */ + dword &= ~((1 << 15) | (1 << 13)); + if(conf) { + if (conf->sata1_enable) { + /* Enable secondary SATA interface */ + dword |= (1<<0); + printk_debug("SATA S \t"); + } + if (conf->sata0_enable) { + /* Enable primary SATA interface */ + dword |= (1<<1); + printk_debug("SATA P \n"); + } + } else { + dword |= (1<<1) | (1<<0); + printk_debug("SATA P and S \n"); + } + + +#if 1 + dword &= ~(0x1f<<24); + dword |= (0x15<<24); +#endif + pci_write_config32(dev, 0x50, dword); + + dword = pci_read_config32(dev, 0xf8); + dword |= 2; + pci_write_config32(dev, 0xf8, dword); + +#endif + +{ +uint32_t i,j; +uint32_t temp32; + +for (i=0;i<10;i++){ + temp32=0; + temp32= pci_read_config32(dev, 0xC0); + for ( j=0;j<0xFFFF;j++); + printk_debug("status= %x",temp32); + if (((temp32&0xF) == 0x3) || ((temp32&0xF) == 0x0)) break; +} +printk_debug("\n"); +} + +#if 0 + +res = find_resource(dev, 0x10); +base =(uint16_t ) res->base; +printk_debug("BASE ADDR %x\n",base); +base&=0xFFFE; +printk_debug("SATA status %x\n",inb(base+7)); + +{ +int i; +for(i=0;i<0xFF;i+=4) +{ + if((i%16)==0) + { + print_debug("\r\n");print_debug_hex8(i);print_debug(" ");} + print_debug_hex32(pci_read_config32(dev,i)); + print_debug(" "); + } +} +#endif +printk_debug("sata_init <--------\r\n"); + +} + +static void lpci_set_subsystem(device_t dev, unsigned vendor, unsigned device) +{ + pci_write_config32(dev, 0x40, + ((device & 0xffff) << 16) | (vendor & 0xffff)); +} +static struct pci_operations lops_pci = { + .set_subsystem = lpci_set_subsystem, +}; + +static struct device_operations sata_ops = { + .read_resources = pci_dev_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_dev_enable_resources, +// .enable = sis966_enable, + .init = sata_init, + .scan_bus = 0, + .ops_pci = &lops_pci, +}; + +static struct pci_driver sata0_driver __pci_driver = { + .ops = &sata_ops, + .vendor = PCI_VENDOR_ID_SIS, + .device = PCI_DEVICE_ID_SIS_SIS966_SATA0, +}; + +static struct pci_driver sata1_driver __pci_driver = { + .ops = &sata_ops, + .vendor = PCI_VENDOR_ID_SIS, + .device = PCI_DEVICE_ID_SIS_SIS966_SATA1, +}; diff --git a/src/southbridge/sis/sis966/sis966_smbus.c b/src/southbridge/sis/sis966/sis966_smbus.c new file mode 100644 index 0000000000..5d1384b440 --- /dev/null +++ b/src/southbridge/sis/sis966/sis966_smbus.c @@ -0,0 +1,154 @@ +/* + * This file is part of the LinuxBIOS project. + * + * Copyright (C) 2004 Tyan Computer + * Written by Yinghai Lu for Tyan Computer. + * Copyright (C) 2006,2007 AMD + * Written by Yinghai Lu for AMD. + * Copyright (C) 2007 Silicon Integrated Systems Corp. (SiS) + * Written by Morgan Tsai for SiS. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "sis966.h" +#include "sis966_smbus.h" + +static int lsmbus_recv_byte(device_t dev) +{ + unsigned device; + struct resource *res; + struct bus *pbus; + + device = dev->path.u.i2c.device; + pbus = get_pbus_smbus(dev); + + res = find_resource(pbus->dev, 0x20 + (pbus->link * 4)); + + return do_smbus_recv_byte(res->base, device); +} + +static int lsmbus_send_byte(device_t dev, uint8_t val) +{ + unsigned device; + struct resource *res; + struct bus *pbus; + + device = dev->path.u.i2c.device; + pbus = get_pbus_smbus(dev); + + res = find_resource(pbus->dev, 0x20 + (pbus->link * 4)); + + return do_smbus_send_byte(res->base, device, val); +} + +static int lsmbus_read_byte(device_t dev, uint8_t address) +{ + unsigned device; + struct resource *res; + struct bus *pbus; + + device = dev->path.u.i2c.device; + pbus = get_pbus_smbus(dev); + + res = find_resource(pbus->dev, 0x20 + (pbus->link * 4)); + + return do_smbus_read_byte(res->base, device, address); +} + +static int lsmbus_write_byte(device_t dev, uint8_t address, uint8_t val) +{ + unsigned device; + struct resource *res; + struct bus *pbus; + + device = dev->path.u.i2c.device; + pbus = get_pbus_smbus(dev); + + res = find_resource(pbus->dev, 0x20 + (pbus->link * 4)); + + return do_smbus_write_byte(res->base, device, address, val); +} +static struct smbus_bus_operations lops_smbus_bus = { + .recv_byte = lsmbus_recv_byte, + .send_byte = lsmbus_send_byte, + .read_byte = lsmbus_read_byte, + .write_byte = lsmbus_write_byte, +}; + +#if HAVE_ACPI_TABLES == 1 +unsigned pm_base; +#endif + +static void sis966_sm_read_resources(device_t dev) +{ + struct resource *res; + unsigned long index; + + /* Get the normal pci resources of this device */ + pci_dev_read_resources(dev); + + for (index = 0x60; index <= 0x68; index+=4) { // We got another 3. + pci_get_resource(dev, index); + } + compact_resources(dev); + +} + +static void sis966_sm_init(device_t dev) +{ +#if HAVE_ACPI_TABLES == 1 + struct resource *res; + + res = find_resource(dev, 0x60); + + if (res) + pm_base = res->base; +#endif +} + +static void lpci_set_subsystem(device_t dev, unsigned vendor, unsigned device) +{ + pci_write_config32(dev, 0x40, + ((device & 0xffff) << 16) | (vendor & 0xffff)); +} + +static struct pci_operations lops_pci = { + .set_subsystem = lpci_set_subsystem, +}; +static struct device_operations smbus_ops = { + .read_resources = sis966_sm_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_dev_enable_resources, + .init = sis966_sm_init, + .scan_bus = scan_static_bus, +// .enable = sis966_enable, + .ops_pci = &lops_pci, + .ops_smbus_bus = &lops_smbus_bus, +}; +static struct pci_driver smbus_driver __pci_driver = { + .ops = &smbus_ops, + .vendor = PCI_VENDOR_ID_SIS, + .device = PCI_DEVICE_ID_SIS_SIS966_SM2, +}; + diff --git a/src/southbridge/sis/sis966/sis966_smbus.h b/src/southbridge/sis/sis966/sis966_smbus.h new file mode 100644 index 0000000000..cc0e1db686 --- /dev/null +++ b/src/southbridge/sis/sis966/sis966_smbus.h @@ -0,0 +1,202 @@ +/* + * This file is part of the LinuxBIOS project. + * + * Copyright (C) 2004 Tyan Computer + * Written by Yinghai Lu for Tyan Computer. + * Copyright (C) 2006,2007 AMD + * Written by Yinghai Lu for AMD. + * Copyright (C) 2007 Silicon Integrated Systems Corp. (SiS) + * Written by Morgan Tsai for SiS. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#define SMBHSTSTAT 0x1 +#define SMBHSTPRTCL 0x0 +#define SMBHSTCMD 0x3 +#define SMBXMITADD 0x2 +#define SMBHSTDAT0 0x4 +#define SMBHSTDAT1 0x5 + +/* Between 1-10 seconds, We should never timeout normally + * Longer than this is just painful when a timeout condition occurs. + */ +#define SMBUS_TIMEOUT (100*1000*10) + +static inline void smbus_delay(void) +{ + outb(0x80, 0x80); +} + +static int smbus_wait_until_ready(unsigned smbus_io_base) +{ + unsigned long loops; + loops = SMBUS_TIMEOUT; + do { + unsigned char val; + smbus_delay(); + val = inb(smbus_io_base + SMBHSTSTAT); + val &= 0x1f; + if (val == 0) { + return 0; + } + outb(val,smbus_io_base + SMBHSTSTAT); + } while(--loops); + return -2; +} + +static int smbus_wait_until_done(unsigned smbus_io_base) +{ + unsigned long loops; + loops = SMBUS_TIMEOUT; + do { + unsigned char val; + smbus_delay(); + + val = inb(smbus_io_base + 0x00); + if ( (val & 0xff) != 0x02) { + return 0; + } + } while(--loops); + return -3; +} +static int do_smbus_recv_byte(unsigned smbus_io_base, unsigned device) +{ + unsigned char global_status_register; + unsigned char byte; + + /* set the device I'm talking too */ + outb(((device & 0x7f) << 1)|1 , smbus_io_base + SMBXMITADD); + smbus_delay(); + + /* byte data recv */ + outb(0x05, smbus_io_base + SMBHSTPRTCL); + smbus_delay(); + + /* poll for transaction completion */ + if (smbus_wait_until_done(smbus_io_base) < 0) { + return -3; + } + + global_status_register = inb(smbus_io_base + SMBHSTSTAT) & 0x80; /* lose check */ + + /* read results of transaction */ + byte = inb(smbus_io_base + SMBHSTCMD); + + if (global_status_register != 0x80) { // lose check, otherwise it should be 0 + return -1; + } + return byte; +} +static int do_smbus_send_byte(unsigned smbus_io_base, unsigned device, unsigned char val) +{ + unsigned global_status_register; + + outb(val, smbus_io_base + SMBHSTDAT0); + smbus_delay(); + + /* set the command... */ + outb(val, smbus_io_base + SMBHSTCMD); + smbus_delay(); + + /* set the device I'm talking too */ + outb(((device & 0x7f) << 1) | 0, smbus_io_base + SMBXMITADD); + smbus_delay(); + + /* set up for a byte data write */ + outb(0x04, smbus_io_base + SMBHSTPRTCL); + smbus_delay(); + + /* poll for transaction completion */ + if (smbus_wait_until_done(smbus_io_base) < 0) { + return -3; + } + global_status_register = inb(smbus_io_base + SMBHSTSTAT) & 0x80; /* lose check */; + + if (global_status_register != 0x80) { + return -1; + } + return 0; +} +static int do_smbus_read_byte(unsigned smbus_io_base, unsigned device, unsigned address) +{ + unsigned char global_status_register; + unsigned char byte; + + outb(0xff, smbus_io_base + 0x00); + smbus_delay(); + outb(0x20, smbus_io_base + 0x03); + smbus_delay(); + + outb(((device & 0x7f) << 1)|1 , smbus_io_base + 0x04); + smbus_delay(); + outb(address & 0xff, smbus_io_base + 0x05); + smbus_delay(); + outb(0x12, smbus_io_base + 0x03); + smbus_delay(); + +int i,j; +for(i=0;i<0x1000;i++) +{ + if (inb(smbus_io_base + 0x00) != 0x08) + { smbus_delay(); + for(j=0;j<0xFFFF;j++); + } +}; + + global_status_register = inb(smbus_io_base + 0x00); + byte = inb(smbus_io_base + 0x08); + + if (global_status_register != 0x08) { // lose check, otherwise it should be 0 + print_debug("Fail");print_debug("\r\t"); + return -1; + } + print_debug("Success");print_debug("\r\t"); + return byte; +} + + +static int do_smbus_write_byte(unsigned smbus_io_base, unsigned device, unsigned address, unsigned char val) +{ + unsigned global_status_register; + + outb(val, smbus_io_base + SMBHSTDAT0); + smbus_delay(); + + /* set the device I'm talking too */ + outb(((device & 0x7f) << 1) | 0, smbus_io_base + SMBXMITADD); + smbus_delay(); + + outb(address & 0xff, smbus_io_base + SMBHSTCMD); + smbus_delay(); + + /* set up for a byte data write */ + outb(0x06, smbus_io_base + SMBHSTPRTCL); + smbus_delay(); + + /* poll for transaction completion */ + if (smbus_wait_until_done(smbus_io_base) < 0) { + return -3; + } + global_status_register = inb(smbus_io_base + SMBHSTSTAT) & 0x80; /* lose check */; + + if (global_status_register != 0x80) { + return -1; + } + return 0; +} + diff --git a/src/southbridge/sis/sis966/sis966_usb.c b/src/southbridge/sis/sis966/sis966_usb.c new file mode 100644 index 0000000000..0cbb68f664 --- /dev/null +++ b/src/southbridge/sis/sis966/sis966_usb.c @@ -0,0 +1,114 @@ +/* + * This file is part of the LinuxBIOS project. + * + * Copyright (C) 2004 Tyan Computer + * Written by Yinghai Lu for Tyan Computer. + * Copyright (C) 2006,2007 AMD + * Written by Yinghai Lu for AMD. + * Copyright (C) 2007 Silicon Integrated Systems Corp. (SiS) + * Written by Morgan Tsai for SiS. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include "sis966.h" + +// From Y.S. +// PCI R47h-R44h=0001AD54h +// PCI R4Bh-R48h=00000271h +uint8_t SiS_SiS7001_init[15][3]={ +{0x04, 0xFF, 0x07}, +{0x2C, 0xFF, 0x39}, +{0x2D, 0xFF, 0x10}, +{0x2E, 0xFF, 0x01}, +{0x2F, 0xFF, 0x70}, +{0x44, 0x00, 0x54}, +{0x45, 0x00, 0xAD}, +{0x46, 0x00, 0x01}, +{0x47, 0x00, 0x00}, +{0x48, 0x00, 0x71}, +{0x49, 0x00, 0x02}, +{0x4A, 0x00, 0x00}, +{0x4B, 0x00, 0x00}, +{0x04, 0x00, 0x07}, +{0x00, 0x00, 0x00} //End of table +}; + +static void usb_init(struct device *dev) +{ + +//-------------- enable USB1.1 (SiS7001) ------------------------- +{ + uint8_t temp8; + int i=0; + + printk_debug("USB1.1_Init\n"); + + while(SiS_SiS7001_init[i][0] != 0) + { temp8 = pci_read_config8(dev, SiS_SiS7001_init[i][0]); + temp8 &= SiS_SiS7001_init[i][1]; + temp8 |= SiS_SiS7001_init[i][2]; + pci_write_config8(dev, SiS_SiS7001_init[i][0], temp8); + i++; + }; +} +//----------------------------------------------------------- + +#if 0 +{ + int i; + printk_debug("\nUSB 1.1 PCI config"); + for(i=0;i<0xFF;i+=4) + { + if((i%16)==0) + { + print_debug("\r\n");print_debug_hex8(i);print_debug(": ");} + print_debug_hex32(pci_read_config32(dev,i)); + print_debug(" "); + } + print_debug("\r\n"); + } +#endif + +} +static void lpci_set_subsystem(device_t dev, unsigned vendor, unsigned device) +{ + pci_write_config32(dev, 0x40, + ((device & 0xffff) << 16) | (vendor & 0xffff)); +} +static struct pci_operations lops_pci = { + .set_subsystem = lpci_set_subsystem, +}; + +static struct device_operations usb_ops = { + .read_resources = pci_dev_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_dev_enable_resources, + .init = usb_init, +// .enable = sis966_enable, + .scan_bus = 0, + .ops_pci = &lops_pci, +}; + +static struct pci_driver usb_driver __pci_driver = { + .ops = &usb_ops, + .vendor = PCI_VENDOR_ID_SIS, + .device = PCI_DEVICE_ID_SIS_SIS966_USB, +}; diff --git a/src/southbridge/sis/sis966/sis966_usb2.c b/src/southbridge/sis/sis966/sis966_usb2.c new file mode 100644 index 0000000000..afd31af198 --- /dev/null +++ b/src/southbridge/sis/sis966/sis966_usb2.c @@ -0,0 +1,168 @@ +/* + * This file is part of the LinuxBIOS project. + * + * Copyright (C) 2004 Tyan Computer + * Written by Yinghai Lu for Tyan Computer. + * Copyright (C) 2006,2007 AMD + * Written by Yinghai Lu for AMD. + * Copyright (C) 2007 Silicon Integrated Systems Corp. (SiS) + * Written by Morgan Tsai for SiS. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include +#include "sis966.h" +#if CONFIG_USBDEBUG_DIRECT +#include +#endif + +extern struct ehci_debug_info dbg_info; + +// From Y.S. +// PCI R43h-R40h=00000020h +// PCI R4Bh-R48h=00078010h +uint8_t SiS_SiS7002_init[19][3]={ +{0x04, 0x00, 0x06}, + +{0x2C, 0xFF, 0x39}, +{0x2D, 0xFF, 0x10}, +{0x2E, 0xFF, 0x02}, +{0x2F, 0xFF, 0x70}, + +{0x74, 0x00, 0x00}, +{0x75, 0x00, 0x00}, +{0x76, 0x00, 0x00}, +{0x77, 0x00, 0x00}, + +{0x40, 0x00, 0x20}, +{0x41, 0x00, 0x00}, +{0x42, 0x00, 0x00}, +{0x43, 0x00, 0x08}, + +{0x44, 0x00, 0x64}, + +{0x48, 0x00, 0x10}, +{0x49, 0x00, 0x80}, +{0x4A, 0x00, 0x07}, +{0x4B, 0x00, 0x00}, + +{0x00, 0x00, 0x00} //End of table +}; + + + +static void usb2_init(struct device *dev) +{ + uint8_t *base; + struct resource *res; + uint32_t temp32; + + +//-------------- enable USB2.0 (SiS7002) ------------------------- +{ + uint8_t temp8; + int i=0; + + printk_debug("USB2.0_Init\n"); + + while(SiS_SiS7002_init[i][0] != 0) + { temp8 = pci_read_config8(dev, SiS_SiS7002_init[i][0]); + temp8 &= SiS_SiS7002_init[i][1]; + temp8 |= SiS_SiS7002_init[i][2]; + pci_write_config8(dev, SiS_SiS7002_init[i][0], temp8); + i++; + }; +} + + res = find_resource(dev, 0x10); + if(!res) + return; + + base =(uint8_t *) res->base; + printk_debug("base = %08x\n", base); + writel(0x2,base+0x20); +//----------------------------------------------------------- + +#if 0 +{ + int i; + printk_debug("\nUSB 2.0 PCI config"); + for(i=0;i<0xFF;i+=4) + { + if((i%16)==0) + { + print_debug("\r\n");print_debug_hex8(i);print_debug(": ");} + print_debug_hex32(pci_read_config32(dev,i)); + print_debug(" "); + } + print_debug("\r\n"); + } +#endif + +} + +static void usb2_set_resources(struct device *dev) +{ +#if CONFIG_USBDEBUG_DIRECT + struct resource *res; + unsigned base; + unsigned old_debug; + + old_debug = get_ehci_debug(); + set_ehci_debug(0); +#endif + pci_dev_set_resources(dev); + +#if CONFIG_USBDEBUG_DIRECT + res = find_resource(dev, 0x10); + set_ehci_debug(old_debug); + if (!res) return; + base = res->base; + set_ehci_base(base); + report_resource_stored(dev, res, ""); +#endif + +} + +static void lpci_set_subsystem(device_t dev, unsigned vendor, unsigned device) +{ + pci_write_config32(dev, 0x40, + ((device & 0xffff) << 16) | (vendor & 0xffff)); +} +static struct pci_operations lops_pci = { + .set_subsystem = lpci_set_subsystem, +}; + +static struct device_operations usb2_ops = { + .read_resources = pci_dev_read_resources, + .set_resources = usb2_set_resources, + .enable_resources = pci_dev_enable_resources, + .init = usb2_init, +// .enable = sis966_enable, + .scan_bus = 0, + .ops_pci = &lops_pci, +}; + +static struct pci_driver usb2_driver __pci_driver = { + .ops = &usb2_ops, + .vendor = PCI_VENDOR_ID_SIS, + .device = PCI_DEVICE_ID_SIS_SIS966_EHCI, +}; diff --git a/src/southbridge/sis/sis966/sisnb.c b/src/southbridge/sis/sis966/sisnb.c new file mode 100644 index 0000000000..c1aa7b3011 --- /dev/null +++ b/src/southbridge/sis/sis966/sisnb.c @@ -0,0 +1,192 @@ +/* + * This file is part of the LinuxBIOS project. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Turn off machine check triggers when reading + * pci space where there are no devices. + * This is necessary when scaning the bus for + * devices which is done by the kernel + * + * written in 2003 by Eric Biederman + * + * - Athlon64 workarounds by Stefan Reinauer + * - "reset once" logic by Yinghai Lu + * Copyright (C) 2007 Silicon Integrated Systems Corp. (SiS) + * Written by Morgan Tsai for SiS. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//#include "amdk8.h" + +#include + +/** + * @brief Read resources for AGP aperture + * + * @param + * + * There is only one AGP aperture resource needed. The resoruce is added to + * the northbridge of BSP. + * + * The same trick can be used to augment legacy VGA resources which can + * be detect by generic pci reousrce allocator for VGA devices. + * BAD: it is more tricky than I think, the resource allocation code is + * implemented in a way to NOT DOING legacy VGA resource allcation on + * purpose :-(. + */ + + +typedef struct msr_struct +{ + unsigned lo; + unsigned hi; +} msr_t; + +static inline msr_t rdmsr(unsigned index) +{ + msr_t result; + result.lo = 0; + result.hi = 0; + return result; +} + + + +static void sisnb_read_resources(device_t dev) +{ + struct resource *resource; + unsigned char iommu; + /* Read the generic PCI resources */ + printk_debug("sisnb_read_resources\n"); + pci_dev_read_resources(dev); + + /* If we are not the first processor don't allocate the gart apeture */ + if (dev->path.u.pci.devfn != PCI_DEVFN(0x0, 0)) { + return; + } + + + return; + + iommu = 1; + get_option(&iommu, "iommu"); + + if (iommu) { + /* Add a Gart apeture resource */ + resource = new_resource(dev, 0x94); + resource->size = iommu?AGP_APERTURE_SIZE:1; + resource->align = log2(resource->size); + resource->gran = log2(resource->size); + resource->limit = 0xffffffff; /* 4G */ + resource->flags = IORESOURCE_MEM; + } +} + +static void set_agp_aperture(device_t dev) +{ + struct resource *resource; + + return; + + resource = probe_resource(dev, 0x94); + if (resource) { + device_t pdev; + uint32_t gart_base, gart_acr; + + /* Remember this resource has been stored */ + resource->flags |= IORESOURCE_STORED; + + /* Find the size of the GART aperture */ + gart_acr = (0<<6)|(0<<5)|(0<<4)|((resource->gran - 25) << 1)|(0<<0); + + /* Get the base address */ + gart_base = ((resource->base) >> 25) & 0x00007fff; + + /* Update the other northbriges */ + pdev = 0; + while((pdev = dev_find_device(PCI_VENDOR_ID_AMD, 0x1103, pdev))) { + /* Store the GART size but don't enable it */ + pci_write_config32(pdev, 0x90, gart_acr); + + /* Store the GART base address */ + pci_write_config32(pdev, 0x94, gart_base); + + /* Don't set the GART Table base address */ + pci_write_config32(pdev, 0x98, 0); + + /* Report the resource has been stored... */ + report_resource_stored(pdev, resource, " "); + } + } +} + +static void sisnb_set_resources(device_t dev) +{ +printk_debug("sisnb_set_resources ------->\n"); + /* Set the gart apeture */ +// set_agp_aperture(dev); + + /* Set the generic PCI resources */ + pci_dev_set_resources(dev); + printk_debug("sisnb_set_resources <-------\n"); +} + +static void sisnb_init(struct device *dev) +{ + uint32_t cmd, cmd_ref; + int needs_reset; + struct device *f0_dev, *f2_dev; + msr_t msr; + + + needs_reset = 0; + printk_debug("sisnb_init: ---------->\n"); + + //dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_SIS, PCI_DEVICE_ID_SIS_SIS756), 0); + msr = rdmsr(0xC001001A); + pci_write_config16(dev, 0x8E, msr.lo >> 16); // Topbound + pci_write_config8(dev, 0x7F, 0x08); // ACPI Base + outb(inb(0x856) | 0x40, 0x856); // Auto-Reset Function + + printk_debug("sisnb_init: <----------\n"); + printk_debug("done.\n"); +} + + +static struct device_operations sisnb_ops = { + .read_resources = sisnb_read_resources, + .set_resources = sisnb_set_resources, + .enable_resources = pci_dev_enable_resources, + .init = sisnb_init, + .scan_bus = 0, + .ops_pci = 0, +}; + +static struct pci_driver sisnb_driver __pci_driver = { + .ops = &sisnb_ops, + .vendor = PCI_VENDOR_ID_SIS, + .device = PCI_DEVICE_ID_SIS_SIS761, +}; -- cgit v1.2.3