From 9095e30f2dbac3c53a380a20d15d4698449dab20 Mon Sep 17 00:00:00 2001 From: Jon Dufresne Date: Thu, 28 Dec 2006 12:00:58 +0000 Subject: A patch to add initial support for the i82801db southbridge based heavily on the code for i82801dbm and i82801er Signed-off-by: Jon Dufresne Acked-by: Ronald G. Minnich git-svn-id: svn://svn.coreboot.org/coreboot/trunk@2534 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1 --- src/southbridge/intel/i82801db/Config.lb | 11 + src/southbridge/intel/i82801db/chip.h | 55 +++ src/southbridge/intel/i82801db/cmos_failover.c | 34 ++ src/southbridge/intel/i82801db/i82801db.c | 64 ++++ src/southbridge/intel/i82801db/i82801db.h | 33 ++ src/southbridge/intel/i82801db/i82801db_ac97.c | 55 +++ .../intel/i82801db/i82801db_early_smbus.c | 158 ++++++++ src/southbridge/intel/i82801db/i82801db_ehci.c | 68 ++++ src/southbridge/intel/i82801db/i82801db_ide.c | 75 ++++ src/southbridge/intel/i82801db/i82801db_lpc.c | 416 +++++++++++++++++++++ src/southbridge/intel/i82801db/i82801db_pci.c | 63 ++++ src/southbridge/intel/i82801db/i82801db_reset.c | 25 ++ src/southbridge/intel/i82801db/i82801db_smbus.c | 63 ++++ src/southbridge/intel/i82801db/i82801db_smbus.h | 123 ++++++ src/southbridge/intel/i82801db/i82801db_uhci.c | 74 ++++ src/southbridge/intel/i82801db/i82801db_watchdog.c | 46 +++ 16 files changed, 1363 insertions(+) create mode 100644 src/southbridge/intel/i82801db/Config.lb create mode 100644 src/southbridge/intel/i82801db/chip.h create mode 100644 src/southbridge/intel/i82801db/cmos_failover.c create mode 100644 src/southbridge/intel/i82801db/i82801db.c create mode 100644 src/southbridge/intel/i82801db/i82801db.h create mode 100644 src/southbridge/intel/i82801db/i82801db_ac97.c create mode 100644 src/southbridge/intel/i82801db/i82801db_early_smbus.c create mode 100644 src/southbridge/intel/i82801db/i82801db_ehci.c create mode 100644 src/southbridge/intel/i82801db/i82801db_ide.c create mode 100644 src/southbridge/intel/i82801db/i82801db_lpc.c create mode 100644 src/southbridge/intel/i82801db/i82801db_pci.c create mode 100644 src/southbridge/intel/i82801db/i82801db_reset.c create mode 100644 src/southbridge/intel/i82801db/i82801db_smbus.c create mode 100644 src/southbridge/intel/i82801db/i82801db_smbus.h create mode 100644 src/southbridge/intel/i82801db/i82801db_uhci.c create mode 100644 src/southbridge/intel/i82801db/i82801db_watchdog.c diff --git a/src/southbridge/intel/i82801db/Config.lb b/src/southbridge/intel/i82801db/Config.lb new file mode 100644 index 0000000..d61fa29 --- /dev/null +++ b/src/southbridge/intel/i82801db/Config.lb @@ -0,0 +1,11 @@ +config chip.h +driver i82801db.o +driver i82801db_uhci.o +driver i82801db_lpc.o +driver i82801db_ide.o +driver i82801db_ehci.o +driver i82801db_smbus.o +driver i82801db_pci.o +driver i82801db_ac97.o +object i82801db_watchdog.o +object i82801db_reset.o diff --git a/src/southbridge/intel/i82801db/chip.h b/src/southbridge/intel/i82801db/chip.h new file mode 100644 index 0000000..76e0560 --- /dev/null +++ b/src/southbridge/intel/i82801db/chip.h @@ -0,0 +1,55 @@ +/* + * 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 + */ + +#ifndef I82801DB_CHIP_H +#define I82801DB_CHIP_H + +struct southbridge_intel_i82801db_config +{ + +#define ICH5R_GPIO_USE_MASK 0x03 +#define ICH5R_GPIO_USE_DEFAULT 0x00 +#define ICH5R_GPIO_USE_AS_NATIVE 0x01 +#define ICH5R_GPIO_USE_AS_GPIO 0x02 + +#define ICH5R_GPIO_SEL_MASK 0x0c +#define ICH5R_GPIO_SEL_DEFAULT 0x00 +#define ICH5R_GPIO_SEL_OUTPUT 0x04 +#define ICH5R_GPIO_SEL_INPUT 0x08 + +#define ICH5R_GPIO_LVL_MASK 0x30 +#define ICH5R_GPIO_LVL_DEFAULT 0x00 +#define ICH5R_GPIO_LVL_LOW 0x10 +#define ICH5R_GPIO_LVL_HIGH 0x20 +#define ICH5R_GPIO_LVL_BLINK 0x30 + +#define ICH5R_GPIO_INV_MASK 0xc0 +#define ICH5R_GPIO_INV_DEFAULT 0x00 +#define ICH5R_GPIO_INV_OFF 0x40 +#define ICH5R_GPIO_INV_ON 0x80 + + /* GPIO use select */ + unsigned char gpio[64]; + unsigned int pirq_a_d; + unsigned int pirq_e_h; + int enable_native_ide; +}; +extern struct chip_operations southbridge_intel_i82801db_ops; + +#endif /* I82801DB_CHIP_H */ + diff --git a/src/southbridge/intel/i82801db/cmos_failover.c b/src/southbridge/intel/i82801db/cmos_failover.c new file mode 100644 index 0000000..5b4bbd2 --- /dev/null +++ b/src/southbridge/intel/i82801db/cmos_failover.c @@ -0,0 +1,34 @@ +/* + * 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 + */ + +//kind of cmos_err for ich5 +#define RTC_FAILED (1 <<2) +#define GEN_PMCON_3 0xa4 +static void check_cmos_failed(void) +{ + + uint8_t byte; + byte = pci_read_config8(PCI_DEV(0,0x1f,0),GEN_PMCON_3); + if( byte & RTC_FAILED){ +//clear bit 1 and bit 2 + byte = cmos_read(RTC_BOOT_BYTE); + byte &= 0x0c; + byte |= MAX_REBOOT_CNT << 4; + cmos_write(byte, RTC_BOOT_BYTE); + } +} diff --git a/src/southbridge/intel/i82801db/i82801db.c b/src/southbridge/intel/i82801db/i82801db.c new file mode 100644 index 0000000..85085ae --- /dev/null +++ b/src/southbridge/intel/i82801db/i82801db.c @@ -0,0 +1,64 @@ +/* + * 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 + */ + +#include +#include +#include +#include +#include "i82801db.h" + +void i82801db_enable(device_t dev) +{ + device_t lpc_dev; + uint16_t word; + + printk_debug("Entering %s\n", __FUNCTION__); + /* See if we are behind the i82801db pci bridge + lpc_dev = dev_find_slot(dev->bus->secondary, PCI_DEVFN(0x1f, 0)); + */ + lpc_dev = dev_find_slot(0, PCI_DEVFN(0x1f, 0)); + if (!lpc_dev) { + return; + } + + word = 0x0040; + pci_write_config16(lpc_dev, 0xf2, word); + /* + if((dev->path.u.pci.devfn &0xf8)== 0xf8) { + index = dev->path.u.pci.devfn & 7; + } + else if((dev->path.u.pci.devfn &0xf8)== 0xe8) { + index = (dev->path.u.pci.devfn & 7) +8; + } + + reg = reg_old = pci_read_config16(lpc_dev, 0xf2); + reg &= ~(1 << index); + if (!dev->enabled) { + reg |= (1 << index); + } + if (reg != reg_old) { + printk_debug("Trying to enable device, [0:1f:0] reg 0xf2 <- %04x\n", reg); + pci_write_config16(lpc_dev, 0xf2, reg); + } + */ +} + +struct chip_operations southbridge_intel_i82801db_ops = { + CHIP_NAME("Intel 82801DB Southbridge") + .enable_dev = i82801db_enable, +}; diff --git a/src/southbridge/intel/i82801db/i82801db.h b/src/southbridge/intel/i82801db/i82801db.h new file mode 100644 index 0000000..54f8587 --- /dev/null +++ b/src/southbridge/intel/i82801db/i82801db.h @@ -0,0 +1,33 @@ +/* + * 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 + */ + +#ifndef I82801DB_H +#define I82801DB_H + +#include "chip.h" + +extern void i82801db_enable(device_t dev); + +#define PCI_DMA_CFG 0x90 +#define SERIRQ_CNTL 0x64 +#define GEN_CNTL 0xd0 +#define GEN_STS 0xd4 +#define RTC_CONF 0xd8 +#define GEN_PMCON_3 0xa4 + +#endif /* I82801DB_H */ diff --git a/src/southbridge/intel/i82801db/i82801db_ac97.c b/src/southbridge/intel/i82801db/i82801db_ac97.c new file mode 100644 index 0000000..b1f8980 --- /dev/null +++ b/src/southbridge/intel/i82801db/i82801db_ac97.c @@ -0,0 +1,55 @@ +/* + * 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 + */ + +#include +#include +#include +#include +#include +#include "i82801db.h" + +static void ac97_set_subsystem(device_t dev, unsigned vendor, unsigned device) +{ + /* Write the subsystem vendor and device id */ + pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID, + ((device & 0xffff) << 16) | (vendor & 0xffff)); +} + +static struct pci_operations lops_pci = { + .set_subsystem = ac97_set_subsystem, +}; +static struct device_operations ac97_ops = { + .read_resources = pci_dev_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_dev_enable_resources, + .init = 0, + .scan_bus = 0, + .enable = i82801db_enable, + .ops_pci = &lops_pci, +}; + +static struct pci_driver ac97_audio_driver __pci_driver = { + .ops = &ac97_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_82801DB_AC97_AUDIO, +}; +static struct pci_driver ac97_modem_driver __pci_driver = { + .ops = &ac97_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_82801DB_AC97_MODEM, +}; diff --git a/src/southbridge/intel/i82801db/i82801db_early_smbus.c b/src/southbridge/intel/i82801db/i82801db_early_smbus.c new file mode 100644 index 0000000..a0d9663 --- /dev/null +++ b/src/southbridge/intel/i82801db/i82801db_early_smbus.c @@ -0,0 +1,158 @@ +/* + * 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 + */ + +#include "i82801db_smbus.h" + +#define SMBUS_IO_BASE 0x0f00 + +static void enable_smbus(void) +{ + device_t dev; + dev = pci_locate_device(PCI_ID(0x8086, 0x24d3), 0); + if (dev == PCI_DEV_INVALID) { + die("SMBUS controller not found\r\n"); + } + print_spew("SMBus controller enabled\r\n"); + + pci_write_config32(dev, 0x20, SMBUS_IO_BASE | 1); + /* Set smbus enable */ + pci_write_config8(dev, 0x40, 1); + /* Set smbus iospace enable */ + pci_write_config8(dev, 0x4, 1); + /* SMBALERT_DIS */ + pci_write_config8(dev, 0x11, 4); + + /* Disable interrupt generation */ + outb(0, SMBUS_IO_BASE + SMBHSTCTL); + + /* clear any lingering errors, so the transaction will run */ + outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT); + +#if 0 // It's unlikely that half the southbridge suddenly vanishes? + dev = pci_locate_device(PCI_ID(0x8086, 0x24d0), 0); + if (dev == PCI_DEV_INVALID) { + die("ISA bridge not found\r\n"); + } +#endif +} + +static int smbus_read_byte(unsigned device, unsigned address) +{ + return do_smbus_read_byte(SMBUS_IO_BASE, device, address); +} + +static void smbus_write_byte(unsigned device, unsigned address, unsigned char val) +{ + if (smbus_wait_until_ready(SMBUS_IO_BASE) < 0) { + return; + } + + print_debug("Unimplemented smbus_write_byte() called.\r\n"); + +#if 0 + /* setup transaction */ + /* disable interrupts */ + outw(inw(SMBUS_IO_BASE + SMBGCTL) & ~((1<<10)|(1<<9)|(1<<8)|(1<<4)), + SMBUS_IO_BASE + SMBGCTL); + /* set the device I'm talking too */ + outw(((device & 0x7f) << 1) | 1, SMBUS_IO_BASE + SMBHSTADDR); + outb(address & 0xFF, SMBUS_IO_BASE + SMBHSTCMD); + /* set up for a byte data write */ /* FIXME */ + outw((inw(SMBUS_IO_BASE + SMBGCTL) & ~7) | (0x1), SMBUS_IO_BASE + SMBGCTL); + /* clear any lingering errors, so the transaction will run */ + /* Do I need to write the bits to a 1 to clear an error? */ + outw(inw(SMBUS_IO_BASE + SMBGSTATUS), SMBUS_IO_BASE + SMBGSTATUS); + + /* clear the data word...*/ + outw(val, SMBUS_IO_BASE + SMBHSTDAT); + + /* start the command */ + outw((inw(SMBUS_IO_BASE + SMBGCTL) | (1 << 3)), SMBUS_IO_BASE + SMBGCTL); + + /* poll for transaction completion */ + smbus_wait_until_done(SMBUS_IO_BASE); +#endif + return; +} + +static int smbus_write_block(unsigned device, unsigned length, unsigned cmd, + unsigned data1, unsigned data2) +{ + unsigned char global_control_register; + unsigned char global_status_register; + unsigned char byte; + unsigned char stat; + int i; + + /* chear the PM timeout flags, SECOND_TO_STS */ + outw(inw(0x0400 + 0x66), 0x0400 + 0x66); + + if (smbus_wait_until_ready(SMBUS_IO_BASE) < 0) { + return -2; + } + + /* setup transaction */ + /* Obtain ownership */ + outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT); + for(stat=0;(stat&0x40)==0;) { + stat = inb(SMBUS_IO_BASE + SMBHSTSTAT); + } + /* clear the done bit */ + outb(0x80, SMBUS_IO_BASE + SMBHSTSTAT); + /* disable interrupts */ + outb(inb(SMBUS_IO_BASE + SMBHSTCTL) & (~1), SMBUS_IO_BASE + SMBHSTCTL); + + /* set the device I'm talking too */ + outb(((device & 0x7f) << 1), SMBUS_IO_BASE + SMBXMITADD); + + /* set the command address */ + outb(cmd & 0xFF, SMBUS_IO_BASE + SMBHSTCMD); + + /* set the block length */ + outb(length & 0xFF, SMBUS_IO_BASE + SMBHSTDAT0); + + /* try sending out the first byte of data here */ + byte=(data1>>(0))&0x0ff; + outb(byte,SMBUS_IO_BASE + SMBBLKDAT); + /* issue a block write command */ + outb((inb(SMBUS_IO_BASE + SMBHSTCTL) & 0xE3) | (0x5 << 2) | 0x40, + SMBUS_IO_BASE + SMBHSTCTL); + + for(i=0;i3) + byte=(data2>>(i%4))&0x0ff; + else + byte=(data1>>(i))&0x0ff; + outb(byte,SMBUS_IO_BASE + SMBBLKDAT); + + /* clear the done bit */ + outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), + SMBUS_IO_BASE + SMBHSTSTAT); + } + + print_debug("SMBUS Block complete\r\n"); + return 0; +} + diff --git a/src/southbridge/intel/i82801db/i82801db_ehci.c b/src/southbridge/intel/i82801db/i82801db_ehci.c new file mode 100644 index 0000000..48b2b0b --- /dev/null +++ b/src/southbridge/intel/i82801db/i82801db_ehci.c @@ -0,0 +1,68 @@ +/* + * 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 + */ + +#include +#include +#include +#include +#include +#include "i82801db.h" + +static void ehci_init(struct device *dev) +{ + uint32_t cmd; + + printk_debug("EHCI: Setting up controller.. "); + cmd = pci_read_config32(dev, PCI_COMMAND); + pci_write_config32(dev, PCI_COMMAND, + cmd | PCI_COMMAND_MASTER); + + printk_debug("done.\n"); +} + +static void ehci_set_subsystem(device_t dev, unsigned vendor, unsigned device) +{ + uint8_t access_cntl; + access_cntl = pci_read_config8(dev, 0x80); + /* Enable writes to protected registers */ + pci_write_config8(dev, 0x80, access_cntl | 1); + /* Write the subsystem vendor and device id */ + pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID, + ((device & 0xffff) << 16) | (vendor & 0xffff)); + /* Restore protection */ + pci_write_config8(dev, 0x80, access_cntl); +} + +static struct pci_operations lops_pci = { + .set_subsystem = &ehci_set_subsystem, +}; +static struct device_operations ehci_ops = { + .read_resources = pci_dev_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_dev_enable_resources, + .init = ehci_init, + .scan_bus = 0, + .enable = i82801db_enable, + .ops_pci = &lops_pci, +}; + +static struct pci_driver ehci_driver __pci_driver = { + .ops = &ehci_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_82801DB_EHCI, +}; diff --git a/src/southbridge/intel/i82801db/i82801db_ide.c b/src/southbridge/intel/i82801db/i82801db_ide.c new file mode 100644 index 0000000..87cb2c3 --- /dev/null +++ b/src/southbridge/intel/i82801db/i82801db_ide.c @@ -0,0 +1,75 @@ +/* + * 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 + */ + +#include +#include +#include +#include +#include +#include "i82801db.h" + +static void ide_init(struct device *dev) +{ + /* Enable IDE devices and timmings */ + uint8_t byte; + + pci_write_config16(dev, 0x40, 0x8000); + /* + pci_write_config16(dev, 0x40, 0xa307); + pci_write_config16(dev, 0x42, 0xa307); + pci_write_config8(dev, 0x48, 0x05); + pci_write_config16(dev, 0x4a, 0x0101); + pci_write_config16(dev, 0x54, 0x5055); + */ + + /* + byte = pci_read_config8(dev, 0x09); + byte |= 0x0f; + pci_write_config8(dev, 0x09, byte); + */ + /* force irq into compat mode + pci_write_config32(dev, 0x10, 0x0); + pci_write_config32(dev, 0x14, 0x0); + pci_write_config32(dev, 0x18, 0x0); + pci_write_config32(dev, 0x1c, 0x0); + + + pci_write_config8(dev, 0x3d, 00); + */ + pci_write_config8(dev, 0x3c, 0xff); + + + + printk_debug("IDE Enabled\n"); +} + +static struct device_operations ide_ops = { + .read_resources = pci_dev_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_dev_enable_resources, + .enable = 0, + .init = ide_init, + .scan_bus = 0, +}; + +static struct pci_driver ide_driver __pci_driver = { + .ops = &ide_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_82801DB_IDE, +}; + diff --git a/src/southbridge/intel/i82801db/i82801db_lpc.c b/src/southbridge/intel/i82801db/i82801db_lpc.c new file mode 100644 index 0000000..d44d829 --- /dev/null +++ b/src/southbridge/intel/i82801db/i82801db_lpc.c @@ -0,0 +1,416 @@ +/* + * 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 + */ + +/* + * (C) 2004 Linux Networx + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include "i82801db.h" + +#define ACPI_BAR 0x40 +#define GPIO_BAR 0x58 + +#define NMI_OFF 0 +#define MAINBOARD_POWER_OFF 0 +#define MAINBOARD_POWER_ON 1 + +#ifndef MAINBOARD_POWER_ON_AFTER_POWER_FAIL +#define MAINBOARD_POWER_ON_AFTER_POWER_FAIL MAINBOARD_POWER_ON +#endif + +#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) + +static void setup_ioapic(void) +{ + int i; + unsigned long value_low, value_high; + unsigned long ioapic_base = 0xfec00000; + volatile unsigned long *l; + unsigned interrupts; + + l = (unsigned long *) ioapic_base; + + l[0] = 0x01; + interrupts = (l[04] >> 16) & 0xff; + for (i = 0; i < interrupts; i++) { + l[0] = (i * 2) + 0x10; + l[4] = DISABLED; + value_low = l[4]; + l[0] = (i * 2) + 0x11; + l[4] = NONE; /* Should this be an address? */ + value_high = l[4]; + if (value_low == 0xffffffff) { + printk_warning("IO APIC not responding.\n"); + return; + } + } + + /* Put the ioapic in virtual wire mode */ + l[0] = 0 + 0x10; + l[4] = ENABLED | TRIGGER_EDGE | POLARITY_HIGH | PHYSICAL_DEST | ExtINT; +} + +#define SERIRQ_CNTL 0x64 +static void i82801db_enable_serial_irqs(device_t dev) +{ + /* set packet length and toggle silent mode bit */ + pci_write_config8(dev, SERIRQ_CNTL, (1 << 7)|(1 << 6)|((21 - 17) << 2)|(0 << 0)); + pci_write_config8(dev, SERIRQ_CNTL, (1 << 7)|(0 << 6)|((21 - 17) << 2)|(0 << 0)); +} + +#define PCI_DMA_CFG 0x90 +static void i82801db_pci_dma_cfg(device_t dev) +{ + /* Set PCI DMA CFG to lpc I/F DMA + pci_write_config16(dev, PCI_DMA_CFG, 0xfcff); */ + pci_write_config16(dev, PCI_DMA_CFG, 0x5455); +} + +#define LPC_EN 0xe6 +static void i82801db_enable_lpc(device_t dev) +{ + /* lpc i/f enable + pci_write_config8(dev, LPC_EN, 0x0d); */ + pci_write_config16(dev, LPC_EN, 0x3403); +} + +typedef struct southbridge_intel_i82801db_config config_t; + +static void set_i82801db_gpio_use_sel( + device_t dev, struct resource *res, config_t *config) +{ + uint32_t gpio_use_sel, gpio_use_sel2; + int i; + + gpio_use_sel = 0x1A003180; + gpio_use_sel2 = 0x00000007; + for(i = 0; i < 64; i++) { + int val; + switch(config->gpio[i] & ICH5R_GPIO_USE_MASK) { + case ICH5R_GPIO_USE_AS_NATIVE: val = 0; break; + case ICH5R_GPIO_USE_AS_GPIO: val = 1; break; + default: + continue; + } + /* The caller is responsible for not playing with unimplemented bits */ + if (i < 32) { + gpio_use_sel &= ~( 1 << i); + gpio_use_sel |= (val << i); + } else { + gpio_use_sel2 &= ~( 1 << (i - 32)); + gpio_use_sel2 |= (val << (i - 32)); + } + } + outl(gpio_use_sel, res->base + 0x00); + outl(gpio_use_sel2, res->base + 0x30); +} + +static void set_i82801db_gpio_direction( + device_t dev, struct resource *res, config_t *config) +{ + uint32_t gpio_io_sel, gpio_io_sel2; + int i; + + gpio_io_sel = 0x0000ffff; + gpio_io_sel2 = 0x00000300; + for(i = 0; i < 64; i++) { + int val; + switch(config->gpio[i] & ICH5R_GPIO_SEL_MASK) { + case ICH5R_GPIO_SEL_OUTPUT: val = 0; break; + case ICH5R_GPIO_SEL_INPUT: val = 1; break; + default: + continue; + } + /* The caller is responsible for not playing with unimplemented bits */ + if (i < 32) { + gpio_io_sel &= ~( 1 << i); + gpio_io_sel |= (val << i); + } else { + gpio_io_sel2 &= ~( 1 << (i - 32)); + gpio_io_sel2 |= (val << (i - 32)); + } + } + outl(gpio_io_sel, res->base + 0x04); + outl(gpio_io_sel2, res->base + 0x34); +} + +static void set_i82801db_gpio_level( + device_t dev, struct resource *res, config_t *config) +{ + uint32_t gpio_lvl, gpio_lvl2; + uint32_t gpio_blink; + int i; + + gpio_lvl = 0x1b3f0000; + gpio_blink = 0x00040000; + gpio_lvl2 = 0x00030207; + for(i = 0; i < 64; i++) { + int val, blink; + switch(config->gpio[i] & ICH5R_GPIO_LVL_MASK) { + case ICH5R_GPIO_LVL_LOW: val = 0; blink = 0; break; + case ICH5R_GPIO_LVL_HIGH: val = 1; blink = 0; break; + case ICH5R_GPIO_LVL_BLINK: val = 1; blink = 1; break; + default: + continue; + } + /* The caller is responsible for not playing with unimplemented bits */ + if (i < 32) { + gpio_lvl &= ~( 1 << i); + gpio_blink &= ~( 1 << i); + gpio_lvl |= ( val << i); + gpio_blink |= (blink << i); + } else { + gpio_lvl2 &= ~( 1 << (i - 32)); + gpio_lvl2 |= (val << (i - 32)); + } + } + outl(gpio_lvl, res->base + 0x0c); + outl(gpio_blink, res->base + 0x18); + outl(gpio_lvl2, res->base + 0x38); +} + +static void set_i82801db_gpio_inv( + device_t dev, struct resource *res, config_t *config) +{ + uint32_t gpio_inv; + int i; + + gpio_inv = 0x00000000; + for(i = 0; i < 32; i++) { + int val; + switch(config->gpio[i] & ICH5R_GPIO_INV_MASK) { + case ICH5R_GPIO_INV_OFF: val = 0; break; + case ICH5R_GPIO_INV_ON: val = 1; break; + default: + continue; + } + gpio_inv &= ~( 1 << i); + gpio_inv |= (val << i); + } + outl(gpio_inv, res->base + 0x2c); +} + +static void i82801db_pirq_init(device_t dev) +{ + config_t *config; + + /* Get the chip configuration */ + config = dev->chip_info; + + if(config->pirq_a_d) { + printk_debug("\n\nIRQs A to D = %04x\n\n", config->pirq_a_d); + pci_write_config32(dev, 0x60, config->pirq_a_d); + } + if(config->pirq_e_h) { + printk_debug("\n\nIRQs e to h = %04x\n\n", config->pirq_e_h); + pci_write_config32(dev, 0x68, config->pirq_e_h); + } +} + + +static void i82801db_gpio_init(device_t dev) +{ + struct resource *res; + config_t *config; + + /* Skip if I don't have any configuration */ + if (!dev->chip_info) { + return; + } + /* The programmer is responsible for ensuring + * a valid gpio configuration. + */ + + /* Get the chip configuration */ + config = dev->chip_info; + /* Find the GPIO bar */ + res = find_resource(dev, GPIO_BAR); + if (!res) { + return; + } + + /* Set the use selects */ + set_i82801db_gpio_use_sel(dev, res, config); + + /* Set the IO direction */ + set_i82801db_gpio_direction(dev, res, config); + + /* Setup the input inverters */ + set_i82801db_gpio_inv(dev, res, config); + + /* Set the value on the GPIO output pins */ + set_i82801db_gpio_level(dev, res, config); + +} + +static void enable_hpet(struct device *dev) +{ +const unsigned long hpet_address = 0xfed0000; + + uint32_t dword; + uint32_t code = (0 & 0x3); + + dword = pci_read_config32(dev, GEN_CNTL); + dword |= (1 << 17); /* enable hpet */ + + /* Bits [16:15] Memory Address Range + * 00 FED0_0000h - FED0_03FFh + * 01 FED0_1000h - FED0_13FFh + * 10 FED0_2000h - FED0_23FFh + * 11 FED0_3000h - FED0_33FFh + */ + + dword &= ~(3 << 15); /* clear it */ + dword |= (code<<15); + + printk_debug("enabling HPET @0x%x\n", hpet_address | (code <<12) ); +} + +static void lpc_init(struct device *dev) +{ + uint8_t byte; + uint32_t value; + int pwr_on=MAINBOARD_POWER_ON_AFTER_POWER_FAIL; + + /* IO APIC initialization */ + value = pci_read_config32(dev, 0xd0); + value |= (1 << 8)|(1<<7)|(1<<1); + pci_write_config32(dev, 0xd0, value); + value = pci_read_config32(dev, 0xd4); + value |= (1<<1); + pci_write_config32(dev, 0xd4, value); + setup_ioapic(); + + i82801db_enable_serial_irqs(dev); + + i82801db_pci_dma_cfg(dev); + + i82801db_enable_lpc(dev); + + /* Clear SATA to non raid + pci_write_config8(dev, 0xae, 0x00); + */ + + get_option(&pwr_on, "power_on_after_fail"); + byte = pci_read_config8(dev, 0xa4); + byte &= 0xfe; + if (!pwr_on) { + byte |= 1; + } + pci_write_config8(dev, 0xa4, byte); + printk_info("set power %s after power fail\n", pwr_on?"on":"off"); + + /* Set up the PIRQ */ + i82801db_pirq_init(dev); + + /* Set the state of the gpio lines */ + i82801db_gpio_init(dev); + + /* Initialize the real time clock */ + rtc_init(0); + + /* Initialize isa dma */ + isa_dma_init(); + + /* Disable IDE (needed when sata is enabled) + pci_write_config8(dev, 0xf2, 0x60); + */ + + enable_hpet(dev); +} + +static void i82801db_lpc_read_resources(device_t dev) +{ + struct resource *res; + + /* Get the normal pci resources of this device */ + pci_dev_read_resources(dev); + + /* Add the ACPI BAR */ + res = pci_get_resource(dev, ACPI_BAR); + + /* Add the GPIO BAR */ + res = pci_get_resource(dev, GPIO_BAR); + + /* 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; +} + +static void i82801db_lpc_enable_resources(device_t dev) +{ + uint8_t acpi_cntl, gpio_cntl; + + /* Enable the normal pci resources */ + pci_dev_enable_resources(dev); + + /* Enable the ACPI bar */ + acpi_cntl = pci_read_config8(dev, 0x44); + acpi_cntl |= (1 << 4); + pci_write_config8(dev, 0x44, acpi_cntl); + + /* Enable the GPIO bar */ + gpio_cntl = pci_read_config8(dev, 0x5c); + gpio_cntl |= (1 << 4); + pci_write_config8(dev, 0x5c, gpio_cntl); + + enable_childrens_resources(dev); +} + +static struct pci_operations lops_pci = { + .set_subsystem = 0, +}; + +static struct device_operations lpc_ops = { + .read_resources = i82801db_lpc_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = i82801db_lpc_enable_resources, + .init = lpc_init, + .scan_bus = scan_static_bus, + .enable = i82801db_enable, + .ops_pci = &lops_pci, +}; + +static struct pci_driver lpc_driver __pci_driver = { + .ops = &lpc_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_82801DB_ISA, +}; diff --git a/src/southbridge/intel/i82801db/i82801db_pci.c b/src/southbridge/intel/i82801db/i82801db_pci.c new file mode 100644 index 0000000..82a2f4e --- /dev/null +++ b/src/southbridge/intel/i82801db/i82801db_pci.c @@ -0,0 +1,63 @@ +/* + * 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 + */ + +#include +#include +#include +#include +#include +#include "i82801db.h" + +static void pci_init(struct device *dev) +{ + uint32_t dword; + uint16_t word; + + /* Clear system errors */ + word = pci_read_config16(dev, 0x06); + word |= 0xf900; /* Clear possible errors */ + pci_write_config16(dev, 0x06, word); + +#if 0 + /* System error enable */ + dword = pci_read_config32(dev, 0x04); + dword |= (1<<8); /* SERR# Enable */ + dword |= (1<<6); /* Parity Error Response */ + pci_write_config32(dev, 0x04, dword); +#endif + + word = pci_read_config16(dev, 0x1e); + word |= 0xf800; /* Clear possible errors */ + pci_write_config16(dev, 0x1e, word); +} + +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, + .ops_pci = 0, +}; + +static struct pci_driver pci_driver __pci_driver = { + .ops = &pci_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_82801DB_PCI, +}; + diff --git a/src/southbridge/intel/i82801db/i82801db_reset.c b/src/southbridge/intel/i82801db/i82801db_reset.c new file mode 100644 index 0000000..e8d6f02 --- /dev/null +++ b/src/southbridge/intel/i82801db/i82801db_reset.c @@ -0,0 +1,25 @@ +/* + * 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 + */ + +#include + +void i82801db_hard_reset(void) +{ + /* Try rebooting through port 0xcf9 */ + outb((0 <<3)|(1<<2)|(1<<1), 0xcf9); +} diff --git a/src/southbridge/intel/i82801db/i82801db_smbus.c b/src/southbridge/intel/i82801db/i82801db_smbus.c new file mode 100644 index 0000000..c6806af --- /dev/null +++ b/src/southbridge/intel/i82801db/i82801db_smbus.c @@ -0,0 +1,63 @@ +/* + * 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 + */ + +#include +#include +#include +#include +#include +#include +#include +#include "i82801db.h" +#include "i82801db_smbus.h" + +static int lsmbus_read_byte(struct bus *bus, device_t dev, uint8_t address) +{ + unsigned device; + struct resource *res; + + device = dev->path.u.i2c.device; + res = find_resource(bus->dev, 0x20); + + return do_smbus_read_byte(res->base, device, address); +} + +static struct smbus_bus_operations lops_smbus_bus = { + .read_byte = lsmbus_read_byte, +}; +static struct pci_operations lops_pci = { + /* The subsystem id follows the ide controller */ + .set_subsystem = 0, +}; +static struct device_operations smbus_ops = { + .read_resources = pci_dev_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_dev_enable_resources, + .init = 0, + .scan_bus = scan_static_bus, + .enable = i82801db_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_INTEL, + .device = PCI_DEVICE_ID_INTEL_82801DB_SMB, +}; + diff --git a/src/southbridge/intel/i82801db/i82801db_smbus.h b/src/southbridge/intel/i82801db/i82801db_smbus.h new file mode 100644 index 0000000..b7ba527 --- /dev/null +++ b/src/southbridge/intel/i82801db/i82801db_smbus.h @@ -0,0 +1,123 @@ +/* + * 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 + */ + +#include + +#define SMBHSTSTAT 0x0 +#define SMBHSTCTL 0x2 +#define SMBHSTCMD 0x3 +#define SMBXMITADD 0x4 +#define SMBHSTDAT0 0x5 +#define SMBHSTDAT1 0x6 +#define SMBBLKDAT 0x7 +#define SMBTRNSADD 0x9 +#define SMBSLVDATA 0xa +#define SMLINK_PIN_CTL 0xe +#define SMBUS_PIN_CTL 0xf + +#define SMBUS_TIMEOUT (100*1000*10) + + +static void smbus_delay(void) +{ + outb(0x80, 0x80); +} + +static int smbus_wait_until_ready(unsigned smbus_io_base) +{ + unsigned loops = SMBUS_TIMEOUT; + unsigned char byte; + do { + smbus_delay(); + if (--loops == 0) + break; + byte = inb(smbus_io_base + SMBHSTSTAT); + } while(byte & 1); + return loops?0:-1; +} + +static int smbus_wait_until_done(unsigned smbus_io_base) +{ + unsigned loops = SMBUS_TIMEOUT; + unsigned char byte; + do { + smbus_delay(); + if (--loops == 0) + break; + byte = inb(smbus_io_base + SMBHSTSTAT); + } while((byte & 1) || (byte & ~((1<<6)|(1<<0))) == 0); + return loops?0:-1; +} + +static int smbus_wait_until_blk_done(unsigned smbus_io_base) +{ + unsigned loops = SMBUS_TIMEOUT; + unsigned char byte; + do { + smbus_delay(); + if (--loops == 0) + break; + byte = inb(smbus_io_base + SMBHSTSTAT); + } while((byte&(1<<7)) == 0); + return loops?0:-1; +} + +static int do_smbus_read_byte(unsigned smbus_io_base, unsigned device, unsigned address) +{ + unsigned char global_status_register; + unsigned char byte; + + if (smbus_wait_until_ready(smbus_io_base) < 0) { + return SMBUS_WAIT_UNTIL_READY_TIMEOUT; + } + /* setup transaction */ + /* disable interrupts */ + outb(inb(smbus_io_base + SMBHSTCTL) & (~1), smbus_io_base + SMBHSTCTL); + /* set the device I'm talking too */ + outb(((device & 0x7f) << 1) | 1, smbus_io_base + SMBXMITADD); + /* set the command/address... */ + outb(address & 0xFF, smbus_io_base + SMBHSTCMD); + /* set up for a byte data read */ + outb((inb(smbus_io_base + SMBHSTCTL) & 0xE3) | (0x2 << 2), smbus_io_base + SMBHSTCTL); + /* clear any lingering errors, so the transaction will run */ + outb(inb(smbus_io_base + SMBHSTSTAT), smbus_io_base + SMBHSTSTAT); + + /* clear the data byte...*/ + outb(0, smbus_io_base + SMBHSTDAT0); + + /* start the command */ + outb((inb(smbus_io_base + SMBHSTCTL) | 0x40), smbus_io_base + SMBHSTCTL); + + /* poll for transaction completion */ + if (smbus_wait_until_done(smbus_io_base) < 0) { + return SMBUS_WAIT_UNTIL_DONE_TIMEOUT; + } + + global_status_register = inb(smbus_io_base + SMBHSTSTAT); + + /* Ignore the In Use Status... */ + global_status_register &= ~(3 << 5); + + /* read results of transaction */ + byte = inb(smbus_io_base + SMBHSTDAT0); + if (global_status_register != (1 << 1)) { + return SMBUS_ERROR; + } + return byte; +} + diff --git a/src/southbridge/intel/i82801db/i82801db_uhci.c b/src/southbridge/intel/i82801db/i82801db_uhci.c new file mode 100644 index 0000000..40f711f --- /dev/null +++ b/src/southbridge/intel/i82801db/i82801db_uhci.c @@ -0,0 +1,74 @@ +/* + * 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 + */ + +#include +#include +#include +#include +#include +#include "i82801db.h" + +static void uhci_init(struct device *dev) +{ + uint32_t cmd; + +#if 1 + printk_debug("UHCI: Setting up controller.. "); + cmd = pci_read_config32(dev, PCI_COMMAND); + pci_write_config32(dev, PCI_COMMAND, + cmd | PCI_COMMAND_MASTER); + + + printk_debug("done.\n"); +#endif + +} + +static struct pci_operations lops_pci = { + /* The subsystem id follows the ide controller */ + .set_subsystem = 0, +}; + +static struct device_operations uhci_ops = { + .read_resources = pci_dev_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_dev_enable_resources, + .init = uhci_init, + .scan_bus = 0, + .enable = i82801db_enable, + .ops_pci = &lops_pci, +}; + +static struct pci_driver uhci_driver __pci_driver = { + .ops = &uhci_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_82801DB_USB0, +}; + +static struct pci_driver usb2_driver __pci_driver = { + .ops = &uhci_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_82801DB_USB1, +}; + +static struct pci_driver usb3_driver __pci_driver = { + .ops = &uhci_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_82801DB_USB2, +}; + diff --git a/src/southbridge/intel/i82801db/i82801db_watchdog.c b/src/southbridge/intel/i82801db/i82801db_watchdog.c new file mode 100644 index 0000000..dab1c69 --- /dev/null +++ b/src/southbridge/intel/i82801db/i82801db_watchdog.c @@ -0,0 +1,46 @@ +/* + * 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 + */ + +#include +#include +#include +#include + +void watchdog_off(void) +{ + device_t dev; + unsigned long value,base; + + /* turn off the ICH5 watchdog */ + dev = dev_find_slot(0, PCI_DEVFN(0x1f,0)); + /* Enable I/O space */ + value = pci_read_config16(dev, 0x04); + value |= (1 << 10); + pci_write_config16(dev, 0x04, value); + /* Get TCO base */ + base = (pci_read_config32(dev, 0x40) & 0x0fffe) + 0x60; + /* Disable the watchdog timer */ + value = inw(base + 0x08); + value |= 1 << 11; + outw(value, base + 0x08); + /* Clear TCO timeout status */ + outw(0x0008, base + 0x04); + outw(0x0002, base + 0x06); + printk_debug("Watchdog ICH5 disabled\r\n"); +} + -- cgit v1.1