From 182615d635343a33306320833b2606e1f966e35a Mon Sep 17 00:00:00 2001 From: "Ronald G. Minnich" Date: Tue, 24 Aug 2004 16:20:46 +0000 Subject: new intel io hub. git-svn-id: svn://svn.coreboot.org/coreboot/trunk@1634 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1 --- src/southbridge/intel/i82801dbm/Config.lb | 11 ++ src/southbridge/intel/i82801dbm/cmos_failover.c | 16 ++ src/southbridge/intel/i82801dbm/i82801dbm.c | 57 ++++++ src/southbridge/intel/i82801dbm/i82801dbm.h | 81 ++++++++ src/southbridge/intel/i82801dbm/i82801dbm_ac97.c | 41 ++++ .../intel/i82801dbm/i82801dbm_early_smbus.c | 156 +++++++++++++++ src/southbridge/intel/i82801dbm/i82801dbm_ide.c | 53 +++++ src/southbridge/intel/i82801dbm/i82801dbm_lpc.c | 219 +++++++++++++++++++++ src/southbridge/intel/i82801dbm/i82801dbm_nic.c | 21 ++ src/southbridge/intel/i82801dbm/i82801dbm_pci.c | 33 ++++ src/southbridge/intel/i82801dbm/i82801dbm_reset.c | 7 + src/southbridge/intel/i82801dbm/i82801dbm_sata.c | 75 +++++++ src/southbridge/intel/i82801dbm/i82801dbm_smbus.c | 92 +++++++++ src/southbridge/intel/i82801dbm/i82801dbm_usb.c | 54 +++++ src/southbridge/intel/i82801dbm/i82801dbm_usb2.c | 39 ++++ 15 files changed, 955 insertions(+) create mode 100644 src/southbridge/intel/i82801dbm/Config.lb create mode 100644 src/southbridge/intel/i82801dbm/cmos_failover.c create mode 100644 src/southbridge/intel/i82801dbm/i82801dbm.c create mode 100644 src/southbridge/intel/i82801dbm/i82801dbm.h create mode 100644 src/southbridge/intel/i82801dbm/i82801dbm_ac97.c create mode 100644 src/southbridge/intel/i82801dbm/i82801dbm_early_smbus.c create mode 100644 src/southbridge/intel/i82801dbm/i82801dbm_ide.c create mode 100644 src/southbridge/intel/i82801dbm/i82801dbm_lpc.c create mode 100644 src/southbridge/intel/i82801dbm/i82801dbm_nic.c create mode 100644 src/southbridge/intel/i82801dbm/i82801dbm_pci.c create mode 100644 src/southbridge/intel/i82801dbm/i82801dbm_reset.c create mode 100644 src/southbridge/intel/i82801dbm/i82801dbm_sata.c create mode 100644 src/southbridge/intel/i82801dbm/i82801dbm_smbus.c create mode 100644 src/southbridge/intel/i82801dbm/i82801dbm_usb.c create mode 100644 src/southbridge/intel/i82801dbm/i82801dbm_usb2.c (limited to 'src') diff --git a/src/southbridge/intel/i82801dbm/Config.lb b/src/southbridge/intel/i82801dbm/Config.lb new file mode 100644 index 0000000000..e7024bd058 --- /dev/null +++ b/src/southbridge/intel/i82801dbm/Config.lb @@ -0,0 +1,11 @@ +config i82801dbm.h +driver i82801dbm.o +driver i82801dbm_usb.o +driver i82801dbm_lpc.o +driver i82801dbm_ide.o +driver i82801dbm_sata.o +driver i82801dbm_usb2.o +driver i82801dbm_ac97.o +#driver i82801dbm_nic.o +#driver i82801dbm_pci.o +object i82801dbm_reset.o diff --git a/src/southbridge/intel/i82801dbm/cmos_failover.c b/src/southbridge/intel/i82801dbm/cmos_failover.c new file mode 100644 index 0000000000..9702313f9c --- /dev/null +++ b/src/southbridge/intel/i82801dbm/cmos_failover.c @@ -0,0 +1,16 @@ +//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/i82801dbm/i82801dbm.c b/src/southbridge/intel/i82801dbm/i82801dbm.c new file mode 100644 index 0000000000..d89a309981 --- /dev/null +++ b/src/southbridge/intel/i82801dbm/i82801dbm.c @@ -0,0 +1,57 @@ +#include +#include +#include +#include +#include +#include "i82801dbm.h" + +void i82801dbm_enable(device_t dev) +{ + device_t lpc_dev; + unsigned int index; + uint16_t reg_old, reg; + +// all 82801dbm device ares in bus 0 + unsigned int devfn; + devfn = PCI_DEVFN(0x1f, 0); // lpc + lpc_dev = dev_find_slot(0, devfn); // 0 + if (!lpc_dev ) { + return; + } +#if 0 + if ((lpc_dev->vendor != PCI_VENDOR_ID_INTEL) || + (lpc_dev->device != PCI_DEVICE_ID_INTEL_82801ER_1F0)) { + uint32_t id; + id = pci_read_config32(lpc_dev, PCI_VENDOR_ID); + if (id != (PCI_VENDOR_ID_INTEL | (PCI_DEVICE_ID_INTEL_82801ER_1F0 << 16))) { + return; + } + } +#endif + + index = (dev->path.u.pci.devfn & 7); + if((dev->path.u.pci.devfn & ~0x7)==devfn) { // D=0x1f + if(index==0){ //1f0 + index = 14; + } + } else { // D=0x1d + index += 8; + } + + reg_old = pci_read_config16(lpc_dev, FUNC_DIS); + reg = reg_old; + reg &= ~(1<enabled) { + reg |= (1< +#include +#include +#include +#include +#include "i82801dbm.h" + + +static struct device_operations ac97audio_ops = { + .read_resources = pci_dev_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_dev_enable_resources, + .enable = i82801dbm_enable, + .init = 0, + .scan_bus = 0, +}; + +static struct pci_driver ac97audio_driver __pci_driver = { + .ops = &ac97audio_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_82801ER_1F5, +}; + + +static struct device_operations ac97modem_ops = { + .read_resources = pci_dev_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_dev_enable_resources, + .enable = i82801dbm_enable, + .init = 0, + .scan_bus = 0, +}; + +static struct pci_driver ac97modem_driver __pci_driver = { + .ops = &ac97modem_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_82801ER_1F6, +}; diff --git a/src/southbridge/intel/i82801dbm/i82801dbm_early_smbus.c b/src/southbridge/intel/i82801dbm/i82801dbm_early_smbus.c new file mode 100644 index 0000000000..ed014f1a86 --- /dev/null +++ b/src/southbridge/intel/i82801dbm/i82801dbm_early_smbus.c @@ -0,0 +1,156 @@ + +//#define SMBUS_IO_BASE 0x1000 +#define SMBUS_IO_BASE 0x0f00 + +#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 + +/* 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 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_debug("SMBus controller enabled\r\n"); + /* set smbus iobase */ + pci_write_config32(dev, 0x20, SMBUS_IO_BASE | 1); + /* Set smbus enable */ + pci_write_config8(dev, 0x40, 0x01); + /* Set smbus iospace enable */ + pci_write_config16(dev, 0x4, 0x01); + /* 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); +} + + +static inline void smbus_delay(void) +{ + outb(0x80, 0x80); +} + +static int smbus_wait_until_ready(void) +{ + unsigned long loops; + loops = SMBUS_TIMEOUT; + do { + unsigned char val; + smbus_delay(); + val = inb(SMBUS_IO_BASE + SMBHSTSTAT); + if ((val & 1) == 0) { + break; + } + if(loops == (SMBUS_TIMEOUT / 2)) { + outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), + SMBUS_IO_BASE + SMBHSTSTAT); + } + } while(--loops); + return loops?0:-2; +} + +static int smbus_wait_until_done(void) +{ + unsigned long loops; + loops = SMBUS_TIMEOUT; + do { + unsigned char val; + smbus_delay(); + + val = inb(SMBUS_IO_BASE + SMBHSTSTAT); + if ( (val & 1) == 0) { + break; + } + if ((val & ~((1<<6)|(1<<0)) ) != 0 ) { + break; + } + } while(--loops); + return loops?0:-3; +} + +static int smbus_read_byte(unsigned device, unsigned address) +{ + unsigned char global_control_register; + unsigned char global_status_register; + unsigned char byte; + + if (smbus_wait_until_ready() < 0) { + return -2; + } + + /* setup transaction */ + /* disable interrupts */ + outb(inb(SMBUS_IO_BASE + SMBHSTCTL) & 0xfe, 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 a byte read, with interrupts disabled */ + outb((inb(SMBUS_IO_BASE + SMBHSTCTL) | 0x40), SMBUS_IO_BASE + SMBHSTCTL); + + + /* poll for transaction completion */ + if (smbus_wait_until_done() < 0) { + return -3; + } + + global_status_register = inb(SMBUS_IO_BASE + SMBHSTSTAT) & ~(1<<6); /* Ignore the In Use Status... */ + + /* read results of transaction */ + byte = inb(SMBUS_IO_BASE + SMBHSTDAT0); + + if (global_status_register != 2) { + return -1; + } + return byte; +} +#if 0 +static void smbus_write_byte(unsigned device, unsigned address, unsigned char val) +{ + if (smbus_wait_until_ready() < 0) { + return; + } + + /* by LYH */ + outb(0x37,SMBUS_IO_BASE + SMBHSTSTAT); + /* set the device I'm talking too */ + outw(((device & 0x7f) << 1) | 0, SMBUS_IO_BASE + SMBHSTADDR); + + /* data to send */ + outb(val, SMBUS_IO_BASE + SMBHSTDAT); + + outb(address & 0xFF, SMBUS_IO_BASE + SMBHSTCMD); + + /* start the command */ + outb(0xa, SMBUS_IO_BASE + SMBHSTCTL); + + /* poll for transaction completion */ + smbus_wait_until_done(); + return; +} +#endif diff --git a/src/southbridge/intel/i82801dbm/i82801dbm_ide.c b/src/southbridge/intel/i82801dbm/i82801dbm_ide.c new file mode 100644 index 0000000000..487fe9f911 --- /dev/null +++ b/src/southbridge/intel/i82801dbm/i82801dbm_ide.c @@ -0,0 +1,53 @@ +#include +#include +#include +#include +#include +#include "i82801dbm.h" + + +static void ide_init(struct device *dev) +{ +#if ICH5_SATA_ADDRESS_MAP<=1 + /* Enable ide devices so the linux ide driver will work */ + uint16_t word; + uint8_t byte; + int enable_a=1, enable_b=1; + + + word = pci_read_config16(dev, 0x40); + word &= ~((1 << 15)); + if (enable_a) { + /* Enable first ide interface */ + word |= (1<<15); + printk_debug("IDE0 "); + } + pci_write_config16(dev, 0x40, word); + + word = pci_read_config16(dev, 0x42); + word &= ~((1 << 15)); + if (enable_a) { + /* Enable secondary ide interface */ + word |= (1<<15); + printk_debug("IDE1 "); + } + pci_write_config16(dev, 0x42, word); +#endif + +} + +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 = i82801dbm_enable, +}; + +static struct pci_driver ide_driver __pci_driver = { + .ops = &ide_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_82801ER_1F1, +}; + diff --git a/src/southbridge/intel/i82801dbm/i82801dbm_lpc.c b/src/southbridge/intel/i82801dbm/i82801dbm_lpc.c new file mode 100644 index 0000000000..7256610765 --- /dev/null +++ b/src/southbridge/intel/i82801dbm/i82801dbm_lpc.c @@ -0,0 +1,219 @@ +/* + * (C) 2003 Linux Networx, SuSE Linux AG + * (C) 2004 Tyan Computer + */ +#include +#include +#include +#include +#include +#include +#include +#include "i82801dbm.h" + +void isa_dma_init(void); /* from /pc80/isa-dma.c */ + +#define NMI_OFF 0 + +void i82801dbm_enable_ioapic( struct device *dev) +{ + uint32_t dword; + volatile uint32_t *ioapic_sba = (volatile uint32_t *)0xfec00000; + volatile uint32_t *ioapic_sbd = (volatile uint32_t *)0xfec00010; + + dword = pci_read_config32(dev, GEN_CNTL); + dword |= (3 << 7); /* enable ioapic */ + dword |= (1 <<13); /* coprocessor error enable */ + dword |= (1 << 1); /* delay transaction enable */ + dword |= (1 << 2); /* DMA collection buf enable */ + pci_write_config32(dev, GEN_CNTL, dword); + printk_debug("ioapic southbridge enabled %x\n",dword); + *ioapic_sba=0; + *ioapic_sbd=(2<<24); + //lyh *ioapic_sba=3; + //lyh *ioapic_sbd=1; + *ioapic_sba=0; + dword=*ioapic_sbd; + printk_debug("Southbridge apic id = %x\n",dword); + if(dword!=(2<<24)) + for(;;); + //lyh *ioapic_sba=3; + //lyh dword=*ioapic_sbd; + //lyh printk_debug("Southbridge apic DT = %x\n",dword); + //lyh if(dword!=1) + //lyh for(;;); + + +} +void i82801dbm_enable_serial_irqs( struct device *dev) +{ + pci_write_config8(dev, SERIRQ_CNTL, (1 << 7)|(1 << 6)|((21 - 17) << 2)|(0<< 0)); +} +void i82801dbm_lpc_route_dma( struct device *dev, uint8_t mask) +{ + uint16_t word; + int i; + word = pci_read_config8(dev, PCI_DMA_CFG); + word &= ((1 << 10) - (1 << 8)); + for(i = 0; i < 8; i++) { + if (i == 4) + continue; + word |= ((mask & (1 << i))? 3:1) << (i*2); + } + pci_write_config16(dev, PCI_DMA_CFG, word); +} +void i82801dbm_rtc_init(struct device *dev) +{ + uint8_t byte; + uint32_t dword; + int rtc_failed; + byte = pci_read_config8(dev, GEN_PMCON_3); + rtc_failed = byte & RTC_FAILED; + if (rtc_failed) { + byte &= ~(1 << 1); /* preserve the power fail state */ + pci_write_config8(dev, GEN_PMCON_3, byte); + } + dword = pci_read_config32(dev, GEN_STS); + rtc_failed |= dword & (1 << 2); + rtc_init(rtc_failed); +} + + +void i82801dbm_1f0_misc(struct device *dev) +{ + pci_write_config16(dev, PCICMD, 0x014f); + pci_write_config32(dev, PMBASE, 0x00001001); + pci_write_config8(dev, ACPI_CNTL, 0x10); + pci_write_config32(dev, GPIO_BASE, 0x00001181); + pci_write_config8(dev, GPIO_CNTL, 0x10); + pci_write_config32(dev, PIRQA_ROUT, 0x0A05030B); + pci_write_config8(dev, PIRQE_ROUT, 0x07); + pci_write_config8(dev, RTC_CONF, 0x04); + pci_write_config8(dev, COM_DEC, 0x10); //lyh E0-> + pci_write_config16(dev, LPC_EN, 0x000F); //LYH 000D-> +} + +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; + int pwr_on=-1; + int nmi_option; + + /* IO APIC initialization */ + i82801dbm_enable_ioapic(dev); + + i82801dbm_enable_serial_irqs(dev); + + /* posted memory write enable */ + byte = pci_read_config8(dev, 0x46); + pci_write_config8(dev, 0x46, byte | (1<<0)); + + /* power after power fail */ + /* FIXME this doesn't work! */ + /* Which state do we want to goto after g3 (power restored)? + * 0 == S0 Full On + * 1 == S5 Soft Off + */ + pci_write_config8(dev, GEN_PMCON_3, pwr_on?0:1); + printk_info("set power %s after power fail\n", pwr_on?"on":"off"); +#if 0 + /* Enable Error reporting */ + /* Set up sync flood detected */ + byte = pci_read_config8(dev, 0x47); + byte |= (1 << 1); + pci_write_config8(dev, 0x47, byte); +#endif + + /* Set up NMI on errors */ + byte = pci_read_config8(dev, 0x61); + byte |= (1 << 3); /* IOCHK# NMI Enable */ + byte |= (1 << 6); /* PCI SERR# Enable */ + pci_write_config8(dev, 0x61, byte); + byte = pci_read_config8(dev, 0x70); + nmi_option = NMI_OFF; + get_option(&nmi_option, "nmi"); + if (nmi_option) { + byte |= (1 << 7); /* set NMI */ + pci_write_config8(dev, 0x70, byte); + } + + /* Initialize the real time clock */ + i82801dbm_rtc_init(dev); + + i82801dbm_lpc_route_dma(dev, 0xff); + + /* Initialize isa dma */ + isa_dma_init(); + + i82801dbm_1f0_misc(dev); + /* Initialize the High Precision Event Timers */ + enable_hpet(dev); +} + +static void i82801dbm_lpc_read_resources(device_t dev) +{ + unsigned int reg; + + /* Get the normal pci resources of this device */ + pci_dev_read_resources(dev); + + /* Find my place in the resource list */ + reg = dev->resources; + + /* Add an extra subtractive resource for both memory and I/O */ + dev->resource[reg].base = 0; + dev->resource[reg].size = 0; + dev->resource[reg].align = 0; + dev->resource[reg].gran = 0; + dev->resource[reg].limit = 0; + dev->resource[reg].flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED; + dev->resource[reg].index = 0; + reg++; + + dev->resource[reg].base = 0; + dev->resource[reg].size = 0; + dev->resource[reg].align = 0; + dev->resource[reg].gran = 0; + dev->resource[reg].limit = 0; + dev->resource[reg].flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED; + dev->resource[reg].index = 0; + reg++; + + dev->resources = reg; +} + +static struct device_operations lpc_ops = { + .read_resources = i82801dbm_lpc_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_dev_enable_resources, + .init = lpc_init, + .scan_bus = scan_static_bus, + .enable = i82801dbm_enable, +}; + +static struct pci_driver lpc_driver __pci_driver = { + .ops = &lpc_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_82801ER_1F0, +}; diff --git a/src/southbridge/intel/i82801dbm/i82801dbm_nic.c b/src/southbridge/intel/i82801dbm/i82801dbm_nic.c new file mode 100644 index 0000000000..5b9c9763a8 --- /dev/null +++ b/src/southbridge/intel/i82801dbm/i82801dbm_nic.c @@ -0,0 +1,21 @@ +#include +#include +#include +#include +#include +#include "i82801dbm.h" + + +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 = 0, + .scan_bus = 0, +}; + +static struct pci_driver nic_driver __pci_driver = { + .ops = &nic_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .device = 0x1051, +}; diff --git a/src/southbridge/intel/i82801dbm/i82801dbm_pci.c b/src/southbridge/intel/i82801dbm/i82801dbm_pci.c new file mode 100644 index 0000000000..20fb1d2ce5 --- /dev/null +++ b/src/southbridge/intel/i82801dbm/i82801dbm_pci.c @@ -0,0 +1,33 @@ +#include +#include +#include +#include +#include +#include "i82801dbm.h" + +static void pci_init(struct device *dev) +{ + /* Enable pci error detecting */ + uint32_t dword; + /* 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); + +} + +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, +}; + +static struct pci_driver pci_driver __pci_driver = { + .ops = &pci_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_82801ER_1E0, +}; + diff --git a/src/southbridge/intel/i82801dbm/i82801dbm_reset.c b/src/southbridge/intel/i82801dbm/i82801dbm_reset.c new file mode 100644 index 0000000000..3d7a4b79b6 --- /dev/null +++ b/src/southbridge/intel/i82801dbm/i82801dbm_reset.c @@ -0,0 +1,7 @@ +#include + +void hard_reset(void) +{ + /* Try rebooting through port 0xcf9 */ + outb((0 <<3)|(1<<2)|(1<<1), 0xcf9); +} diff --git a/src/southbridge/intel/i82801dbm/i82801dbm_sata.c b/src/southbridge/intel/i82801dbm/i82801dbm_sata.c new file mode 100644 index 0000000000..2bc287fa36 --- /dev/null +++ b/src/southbridge/intel/i82801dbm/i82801dbm_sata.c @@ -0,0 +1,75 @@ +#include +#include +#include +#include +#include +#include "i82801dbm.h" + +static void sata_init(struct device *dev) +{ + + uint16_t word; + uint8_t byte; + int enable_c=1, enable_d=1; + int i; + + //Enable Serial ATA port + byte = pci_read_config8(dev,0x90); + byte &= 0xf8; + byte |= ICH5_SATA_ADDRESS_MAP & 7; + pci_write_config8(dev,0x90,byte); + +// for(i=0;i<10;i++) { + word = pci_read_config16(dev,0x92); + word &= 0xfffc; +// if( (word & 0x0003) == 0x0003) break; + word |= 0x0003; // enable P0/P1 + pci_write_config16(dev,0x92,word); +// } + +// for(i=0;i<10;i++) { + /* enable ide0 */ + word = pci_read_config16(dev, 0x40); + word &= ~(1 << 15); + if(enable_c==0) { +// if( (word & 0x8000) == 0x0000) break; + word |= 0x0000; + } + else { +// if( (word & 0x8000) == 0x8000) break; + word |= 0x8000; + } + pci_write_config16(dev, 0x40, word); +// } + /* enable ide1 */ +// for(i=0;i<10;i++) { + word = pci_read_config16(dev, 0x42); + word &= ~(1 << 15); + if(enable_d==0) { +// if( (word & 0x8000) == 0x0000) break; + word |= 0x0000; + } + else { +// if( (word & 0x8000) == 0x8000) break; + word |= 0x8000; + } + pci_write_config16(dev, 0x42, word); +// } + +} + +static struct device_operations sata_ops = { + .read_resources = pci_dev_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_dev_enable_resources, + .init = sata_init, + .scan_bus = 0, + .enable = i82801dbm_enable, +}; + +static struct pci_driver stat_driver __pci_driver = { + .ops = &sata_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_82801ER_1F2_R, +}; + diff --git a/src/southbridge/intel/i82801dbm/i82801dbm_smbus.c b/src/southbridge/intel/i82801dbm/i82801dbm_smbus.c new file mode 100644 index 0000000000..fd06871234 --- /dev/null +++ b/src/southbridge/intel/i82801dbm/i82801dbm_smbus.c @@ -0,0 +1,92 @@ +#include +#include +#include + +#define PM_BUS 0 +#define PM_DEVFN PCI_DEVFN(0x1f,3) + +#define SMBUS_IO_BASE 0x1000 +#define SMBHSTSTAT 0 +#define SMBHSTCTL 2 +#define SMBHSTCMD 3 +#define SMBHSTADD 4 +#define SMBHSTDAT0 5 +#define SMBHSTDAT1 6 +#define SMBBLKDAT 7 + +void smbus_enable(void) +{ + unsigned char byte; + /* iobase addr */ + pcibios_write_config_dword(PM_BUS, PM_DEVFN, 0x20, SMBUS_IO_BASE | 1); + /* smbus enable */ + pcibios_write_config_byte(PM_BUS, PM_DEVFN, 0x40, 1); + /* iospace enable */ + pcibios_write_config_word(PM_BUS, PM_DEVFN, 0x4, 1); + + /* Disable interrupt generation */ + outb(0, SMBUS_IO_BASE + SMBHSTCTL); + +} + +void smbus_setup(void) +{ + outb(0, SMBUS_IO_BASE + SMBHSTSTAT); +} + +static void smbus_wait_until_ready(void) +{ + while((inb(SMBUS_IO_BASE + SMBHSTSTAT) & 1) == 1) { + /* nop */ + } +} + +static void smbus_wait_until_done(void) +{ + unsigned char byte; + do { + byte = inb(SMBUS_IO_BASE + SMBHSTSTAT); + } + while((byte &1) == 1); + while( (byte & ~1) == 0) { + byte = inb(SMBUS_IO_BASE + SMBHSTSTAT); + } +} + +int smbus_read_byte(unsigned device, unsigned address, unsigned char *result) +{ + unsigned char host_status_register; + unsigned char byte; + + smbus_wait_until_ready(); + + /* 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 + SMBHSTADD); + /* 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 */ + smbus_wait_until_done(); + + host_status_register = inb(SMBUS_IO_BASE + SMBHSTSTAT); + + /* read results of transaction */ + byte = inb(SMBUS_IO_BASE + SMBHSTDAT0); + + *result = byte; + return host_status_register != 0x02; +} diff --git a/src/southbridge/intel/i82801dbm/i82801dbm_usb.c b/src/southbridge/intel/i82801dbm/i82801dbm_usb.c new file mode 100644 index 0000000000..b810f59289 --- /dev/null +++ b/src/southbridge/intel/i82801dbm/i82801dbm_usb.c @@ -0,0 +1,54 @@ +#include +#include +#include +#include +#include +#include "i82801dbm.h" + +static void usb_init(struct device *dev) +{ + uint32_t cmd; + +#if 0 + printk_debug("USB: Setting up controller.. "); + cmd = pci_read_config32(dev, PCI_COMMAND); + pci_write_config32(dev, PCI_COMMAND, + cmd | PCI_COMMAND_IO | PCI_COMMAND_MEMORY | + PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE); + + + printk_debug("done.\n"); +#endif + +} + +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, + .scan_bus = 0, + .enable = i82801dbm_enable, +}; + +static struct pci_driver usb_driver_1 __pci_driver = { + .ops = &usb_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_82801ER_1D0, +}; +static struct pci_driver usb_driver_2 __pci_driver = { + .ops = &usb_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_82801ER_1D1, +}; +static struct pci_driver usb_driver_3 __pci_driver = { + .ops = &usb_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_82801ER_1D2, +}; +static struct pci_driver usb_driver_4 __pci_driver = { + .ops = &usb_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_82801ER_1D3, +}; + diff --git a/src/southbridge/intel/i82801dbm/i82801dbm_usb2.c b/src/southbridge/intel/i82801dbm/i82801dbm_usb2.c new file mode 100644 index 0000000000..5b7465da05 --- /dev/null +++ b/src/southbridge/intel/i82801dbm/i82801dbm_usb2.c @@ -0,0 +1,39 @@ +//2003 Copywright Tyan + +#include +#include +#include +#include +#include +#include "i82801dbm.h" + +static void usb2_init(struct device *dev) +{ + uint32_t cmd; + +#if 0 + printk_debug("USB: Setting up controller.. "); + cmd = pci_read_config32(dev, PCI_COMMAND); + pci_write_config32(dev, PCI_COMMAND, + cmd | PCI_COMMAND_IO | PCI_COMMAND_MEMORY | + PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE); + + + printk_debug("done.\n"); +#endif +} + +static struct device_operations usb2_ops = { + .read_resources = pci_dev_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_dev_enable_resources, + .init = usb2_init, + .scan_bus = 0, + .enable = i82801dbm_enable, +}; + +static struct pci_driver usb2_driver __pci_driver = { + .ops = &usb2_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_82801ER_1D7, +}; -- cgit v1.2.3