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, +}; diff --git a/targets/sis/churchill/Config.lb b/targets/sis/churchill/Config.lb new file mode 100644 index 0000000000..863cc89c55 --- /dev/null +++ b/targets/sis/churchill/Config.lb @@ -0,0 +1,117 @@ +## +## 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 +## + +target churchill +mainboard sis/sis761 + +# serengeti_leopard + +romimage "normal" +# 48K for VGA BIOS + option ROM_SIZE = 475136 +# 48K for SCSI FW and 48K for ATI ROM +# option ROM_SIZE = 425984 +# 64K for Etherboot +# option ROM_SIZE = 458752 +# 44k for atixx.rom +# option ROM_SIZE = 479232 +# 32k for vbios +# option ROM_SIZE = 491520 + + option USE_FAILOVER_IMAGE=0 +# option ROM_IMAGE_SIZE=0x13800 +# option ROM_IMAGE_SIZE=0x18800 +# option ROM_IMAGE_SIZE=0x19800 + option ROM_IMAGE_SIZE=0x20000 +# option ROM_IMAGE_SIZE=0x15800 + option XIP_ROM_SIZE=0x40000 + option LINUXBIOS_EXTRA_VERSION="$(shell cat ../../VERSION)_Normal" +# payload ../../../payloads/tg3--ide_disk.zelf +# payload ../../../payloads/filo.elf +# payload ../../../../payloads/filo.elf +# payload ../../../../payloads/filo_hdc1.elf + payload ../../../../payloads/filo_uda1.elf +# payload ../../../payloads/filo_mem.elf +# payload ../../../payloads/filo.zelf +# payload ../../../payloads/tg3--filo_hda2.zelf +# payload ../../../payloads/tg3.zelf +# payload ../../../../payloads/tg3_vga.zelf +# payload ../../../../payloads/tg3--filo_hda2_vga.zelf +# payload ../../../../payloads/tg3--filo_hda2_vga_5_4.zelf +# payload ../../../../payloads/forcedeth--filo_hda2_vga.zelf +# payload ../../../../payloads/forcedeth--filo_hda2_vga_5_4_2_mcp55.zelf +# payload /etc/hosts +# payload ../../../payloads/tg3_com2.zelf +# payload ../../../payloads/e1000--filo.zelf +# payload ../../../payloads/tg3--e1000--filo.zelf +# payload ../../../payloads/tg3--eepro100--e1000--filo_hda2.zelf +# payload ../../../payloads/tg3--eepro100--e1000--filo_hda2_5.3.zelf +# payload ../../../payloads/tg3--eepro100--e1000--filo_hda2_com2.zelf +end + +romimage "fallback" + option USE_FAILOVER_IMAGE=0 + option USE_FALLBACK_IMAGE=1 +# option ROM_IMAGE_SIZE=0x13800 +# option ROM_IMAGE_SIZE=0x18800 +# option ROM_IMAGE_SIZE=0x19800 + option ROM_IMAGE_SIZE=0x20000 +# option ROM_IMAGE_SIZE=0x15800 + option XIP_ROM_SIZE=0x40000 + option LINUXBIOS_EXTRA_VERSION="$(shell cat ../../VERSION)_Fallback" +# payload ../../../payloads/tg3--ide_disk.zelf +# payload ../../../payloads/filo.elf +# payload ../../../payloads/filo_mem.elf +# payload ../../../payloads/filo.zelf +# payload ../../../../payloads/filo.elf +# payload ../../../../payloads/filo_hdc1.elf + payload ../../../../payloads/filo_uda1.elf +# payload ../../../payloads/tg3--filo_hda2.zelf +# payload ../../../payloads/tg3.zelf +# payload ../../../../payloads/tg3_vga.zelf +# payload ../../../../payloads/memtest +# payload ../../../../payloads/e1000_vga.zelf +# payload ../../../../payloads/tg3--filo_hda2_vga.zelf +# payload ../../../../payloads/filo_hda.zelf +# payload ../../../../payloads/adlo.elf +# payload ../../../../payloads/tg3--filo_hda2_vga_5_4.zelf +# payload ../../../../payloads/forcedeth_mcp55_filo_hda2.zelf +# payload ../../../../payloads/forcedeth--filo_hda2_vga_5_4_2_mcp55.zelf +# payload /etc/hosts +# payload ../../../../payloads/forcedeth--filo_hda2_vga.zelf +# payload ../../../payloads/tg3_com2.zelf +# payload ../../../payloads/e1000--filo.zelf +# payload ../../../payloads/tg3--e1000--filo.zelf +# payload ../../../payloads/tg3--eepro100--e1000--filo_hda2.zelf +# payload ../../../payloads/tg3--eepro100--e1000--filo_hda2_5.3.zelf +# payload ../../../payloads/tg3--eepro100--e1000--filo_hda2_com2.zelf +end + +romimage "failover" + option USE_FAILOVER_IMAGE=1 + option USE_FALLBACK_IMAGE=0 + option ROM_IMAGE_SIZE=FAILOVER_SIZE + option XIP_ROM_SIZE=FAILOVER_SIZE + option LINUXBIOS_EXTRA_VERSION="$(shell cat ../../VERSION)_Failover" +end + +# buildrom ./linuxbios.rom ROM_SIZE "normal" "fallback" + buildrom ./linuxbios.rom ROM_SIZE "normal" "fallback" "failover" diff --git a/targets/sis/churchill/README b/targets/sis/churchill/README new file mode 100644 index 0000000000..351d743041 --- /dev/null +++ b/targets/sis/churchill/README @@ -0,0 +1,3 @@ +## How to append VGA bios? + +cat 6330VGA.rom churchill/linuxbios.rom > churchill.bin diff --git a/targets/sis/churchill/VERSION b/targets/sis/churchill/VERSION new file mode 100644 index 0000000000..8775da4b7a --- /dev/null +++ b/targets/sis/churchill/VERSION @@ -0,0 +1 @@ +_churchill