Author: stepan Date: 2009-03-11 15:54:18 +0100 (Wed, 11 Mar 2009) New Revision: 3991
Added: trunk/coreboot-v2/src/southbridge/intel/i82801gx/i82801gx_usb_debug.c Removed: trunk/coreboot-v2/src/southbridge/intel/i82801gx/IOMAP Modified: trunk/coreboot-v2/src/mainboard/kontron/986lcd-m/Config.lb trunk/coreboot-v2/src/mainboard/kontron/986lcd-m/Options.lb trunk/coreboot-v2/src/southbridge/intel/i82801gx/Config.lb trunk/coreboot-v2/src/southbridge/intel/i82801gx/chip.h trunk/coreboot-v2/src/southbridge/intel/i82801gx/cmos_failover.c trunk/coreboot-v2/src/southbridge/intel/i82801gx/i82801gx.c trunk/coreboot-v2/src/southbridge/intel/i82801gx/i82801gx.h trunk/coreboot-v2/src/southbridge/intel/i82801gx/i82801gx_ac97.c trunk/coreboot-v2/src/southbridge/intel/i82801gx/i82801gx_azalia.c trunk/coreboot-v2/src/southbridge/intel/i82801gx/i82801gx_early_smbus.c trunk/coreboot-v2/src/southbridge/intel/i82801gx/i82801gx_ide.c trunk/coreboot-v2/src/southbridge/intel/i82801gx/i82801gx_lpc.c trunk/coreboot-v2/src/southbridge/intel/i82801gx/i82801gx_nic.c trunk/coreboot-v2/src/southbridge/intel/i82801gx/i82801gx_pci.c trunk/coreboot-v2/src/southbridge/intel/i82801gx/i82801gx_pcie.c trunk/coreboot-v2/src/southbridge/intel/i82801gx/i82801gx_reset.c trunk/coreboot-v2/src/southbridge/intel/i82801gx/i82801gx_sata.c trunk/coreboot-v2/src/southbridge/intel/i82801gx/i82801gx_smbus.c trunk/coreboot-v2/src/southbridge/intel/i82801gx/i82801gx_smbus.h trunk/coreboot-v2/src/southbridge/intel/i82801gx/i82801gx_usb.c trunk/coreboot-v2/src/southbridge/intel/i82801gx/i82801gx_usb_ehci.c trunk/coreboot-v2/src/southbridge/intel/i82801gx/i82801gx_watchdog.c Log: This patch contains some significant updates to the i82801gx component and will be required for a series of later patches. Roughly it contains:
* fixed SMBus driver (was not compiled in before) * fixed S-ATA/P-ATA combination * Added warnings to drivers being called with a NULL dev->chip_info * Set subsystem ids for those boards that have none specified in Options.lb * Fix license headers. The code was originally released under GPL v2 but some files sneaked in with a v2 or later header. * some attempts to fix azalia/Intel HDA.. not working yet * clean up and fix pci bridge handling code * Add Config based GPI handling to LPC driver * Add HPET enable function * Enable clock gating where appropriate * first attempt at USB debug console support (not working yet) * Add required options to kontron board * many other minor changes
Signed-off-by: Stefan Reinauer stepan@coresystems.de Acked-by: Myles Watson mylesgw@gmail.com
Modified: trunk/coreboot-v2/src/mainboard/kontron/986lcd-m/Config.lb =================================================================== --- trunk/coreboot-v2/src/mainboard/kontron/986lcd-m/Config.lb 2009-03-11 14:48:20 UTC (rev 3990) +++ trunk/coreboot-v2/src/mainboard/kontron/986lcd-m/Config.lb 2009-03-11 14:54:18 UTC (rev 3991) @@ -190,13 +190,19 @@ chip southbridge/intel/i82801gx register "pirqa_routing" = "0x05" register "pirqb_routing" = "0x07" - register "pirqc_routing" = "0x06" + register "pirqc_routing" = "0x05" register "pirqd_routing" = "0x07" register "pirqe_routing" = "0x80" register "pirqf_routing" = "0x80" register "pirqg_routing" = "0x80" - register "pirqh_routing" = "0x05" + register "pirqh_routing" = "0x06"
+ # GPI routing + # 0 No effect (default) + # 1 SMI# (if corresponding ALT_GPI_SMI_EN bit is also set) + # 2 SCI (if corresponding GPIO_EN bit is also set) + register "gpi13_routing" = "1" + register "ide_legacy_combined" = "0x1" register "ide_enable_primary" = "0x1" register "ide_enable_secondary" = "0x0"
Modified: trunk/coreboot-v2/src/mainboard/kontron/986lcd-m/Options.lb =================================================================== --- trunk/coreboot-v2/src/mainboard/kontron/986lcd-m/Options.lb 2009-03-11 14:48:20 UTC (rev 3990) +++ trunk/coreboot-v2/src/mainboard/kontron/986lcd-m/Options.lb 2009-03-11 14:54:18 UTC (rev 3991) @@ -69,6 +69,9 @@ uses HAVE_HARD_RESET uses HAVE_SMI_HANDLER uses CONFIG_PCIE_CONFIGSPACE_HOLE +uses MMCONF_SUPPORT +uses MMCONF_BASE_ADDRESS +uses CONFIG_GFXUMA # uses MAINBOARD uses MAINBOARD_PART_NUMBER @@ -86,7 +89,9 @@ uses DEFAULT_CONSOLE_LOGLEVEL uses MAXIMUM_CONSOLE_LOGLEVEL uses CONFIG_CONSOLE_VGA +uses CONFIG_VGA_ROM_RUN uses CONFIG_PCI_ROM_RUN +uses DEBUG # Toolchain uses CC uses HOSTCC @@ -145,8 +150,15 @@ ##
default CONFIG_PCIE_CONFIGSPACE_HOLE=1 +default MMCONF_SUPPORT=1 +default MMCONF_BASE_ADDRESS=0xf0000000
## +## UMA +## +default CONFIG_GFXUMA=1 + +## ## Build code to export a programmable irq routing table ## default HAVE_PIRQ_TABLE=1 @@ -163,7 +175,7 @@ ## default HAVE_ACPI_TABLES=1 default HAVE_MAINBOARD_RESOURCES=1 -default HAVE_HIGH_TABLES=0 +default HAVE_HIGH_TABLES=1
## ## Build code to export a CMOS option table @@ -179,7 +191,12 @@
#VGA Console default CONFIG_CONSOLE_VGA=1 -default CONFIG_PCI_ROM_RUN=1 +# There are some network option roms that don't work with +# coreboot's x86emu. Thus, we only execute the VGA option rom +# for now: +default CONFIG_VGA_ROM_RUN=1 +default CONFIG_PCI_ROM_RUN=0 +default DEBUG=0
## ## Build code for SMP support
Modified: trunk/coreboot-v2/src/southbridge/intel/i82801gx/Config.lb =================================================================== --- trunk/coreboot-v2/src/southbridge/intel/i82801gx/Config.lb 2009-03-11 14:48:20 UTC (rev 3990) +++ trunk/coreboot-v2/src/southbridge/intel/i82801gx/Config.lb 2009-03-11 14:54:18 UTC (rev 3991) @@ -5,8 +5,7 @@ ## ## 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. +## the Free Software Foundation; version 2 of the License. ## ## This program is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -30,6 +29,7 @@ driver i82801gx_pci.o driver i82801gx_pcie.o driver i82801gx_sata.o +driver i82801gx_smbus.o driver i82801gx_usb.o driver i82801gx_usb_ehci.o
Deleted: trunk/coreboot-v2/src/southbridge/intel/i82801gx/IOMAP =================================================================== --- trunk/coreboot-v2/src/southbridge/intel/i82801gx/IOMAP 2009-03-11 14:48:20 UTC (rev 3990) +++ trunk/coreboot-v2/src/southbridge/intel/i82801gx/IOMAP 2009-03-11 14:54:18 UTC (rev 3991) @@ -1,35 +0,0 @@ -Non-automatic IO-Addresses --------------------------- - -The following dynamic IO BARs are used on the ICH7 for the Kontron Default BIOS: - -GPIOBASE 0x480 (64 bytes) -PMBASE 0x800 (128 bytes) -SMBASE 0x400 (32 bytes) -HWMON 0xa00 (??) - -The following dynamic IO BARs are used on the ICH7 for the Getac Default BIOS: - -GPIOBASE 0x1180 (64 bytes) -PMBASE 0x1000 (128 bytes) -SMBASE 0x18e0 (32 bytes) - -The Getac also needs an IO Trapped area of 0x0C bytes (defaults to 0x800) - -coreboot: -GPIOBASE 0x480 (64 bytes) -PMBASE 0x500 (128 bytes) -SMBASE 0x400 (32 bytes) -HWMON 0xa00 (??) - - - -NOTE: Coreboot sets the SMBASE to 0xf00 in auto.c. But it gets relocated -in stage2 because its a "normal BAR" (to 0x2080 in one case here). - -This is not unhealthy but at least confusing. We should provide a method to -nail down certain resources for stage2. - -For a list of static I/O space allocation look at 6.3.1 of the ICH7 Family -Datasheet. -
Modified: trunk/coreboot-v2/src/southbridge/intel/i82801gx/chip.h =================================================================== --- trunk/coreboot-v2/src/southbridge/intel/i82801gx/chip.h 2009-03-11 14:48:20 UTC (rev 3990) +++ trunk/coreboot-v2/src/southbridge/intel/i82801gx/chip.h 2009-03-11 14:54:18 UTC (rev 3991) @@ -3,10 +3,10 @@ * * Copyright (C) 2008-2009 coresystems GmbH * - * 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 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; version 2 of + * the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -22,7 +22,10 @@ #define SOUTHBRIDGE_INTEL_I82801GX_CHIP_H
struct southbridge_intel_i82801gx_config { - /* LPC configuration */ + /** + * Interrupt Routing configuration + * If bit7 is 1, the interrupt is disabled. + */ uint8_t pirqa_routing; uint8_t pirqb_routing; uint8_t pirqc_routing; @@ -32,6 +35,32 @@ uint8_t pirqg_routing; uint8_t pirqh_routing;
+ /** + * GPI Routing configuration + * + * Only the lower two bits have a meaning: + * 00: No effect + * 01: SMI# (if corresponding ALT_GPI_SMI_EN bit is also set) + * 10: SCI (if corresponding GPIO_EN bit is also set) + * 11: reserved + */ + uint8_t gpi0_routing; + uint8_t gpi1_routing; + uint8_t gpi2_routing; + uint8_t gpi3_routing; + uint8_t gpi4_routing; + uint8_t gpi5_routing; + uint8_t gpi6_routing; + uint8_t gpi7_routing; + uint8_t gpi8_routing; + uint8_t gpi9_routing; + uint8_t gpi10_routing; + uint8_t gpi11_routing; + uint8_t gpi12_routing; + uint8_t gpi13_routing; + uint8_t gpi14_routing; + uint8_t gpi15_routing; + /* IDE configuration */ uint32_t ide_legacy_combined; uint32_t ide_enable_primary; @@ -39,7 +68,7 @@ uint32_t sata_ahci;
/* Azalia Configuration */ - unsigned long hda_viddid; + uint32_t hda_viddid; };
extern struct chip_operations southbridge_intel_i82801gx_ops;
Modified: trunk/coreboot-v2/src/southbridge/intel/i82801gx/cmos_failover.c =================================================================== --- trunk/coreboot-v2/src/southbridge/intel/i82801gx/cmos_failover.c 2009-03-11 14:48:20 UTC (rev 3990) +++ trunk/coreboot-v2/src/southbridge/intel/i82801gx/cmos_failover.c 2009-03-11 14:54:18 UTC (rev 3991) @@ -1,11 +1,13 @@ /* * This file is part of the coreboot 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. + * (C) 2008-2009 coresystems GmbH * + * 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; version 2 of + * the License. + * * 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
Modified: trunk/coreboot-v2/src/southbridge/intel/i82801gx/i82801gx.c =================================================================== --- trunk/coreboot-v2/src/southbridge/intel/i82801gx/i82801gx.c 2009-03-11 14:48:20 UTC (rev 3990) +++ trunk/coreboot-v2/src/southbridge/intel/i82801gx/i82801gx.c 2009-03-11 14:54:18 UTC (rev 3991) @@ -1,12 +1,12 @@ /* * This file is part of the coreboot project. * - * Copyright (C) 2008 coresystems GmbH + * Copyright (C) 2008-2009 coresystems GmbH * - * 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 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; version 2 of + * the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -25,6 +25,12 @@
void i82801gx_enable(device_t dev) { + u32 reg32; + + /* Enable SERR */ + reg32 = pci_read_config32(dev, PCI_COMMAND); + reg32 |= PCI_COMMAND_SERR; + pci_write_config32(dev, PCI_COMMAND, reg32); }
struct chip_operations southbridge_intel_i82801gx_ops = {
Modified: trunk/coreboot-v2/src/southbridge/intel/i82801gx/i82801gx.h =================================================================== --- trunk/coreboot-v2/src/southbridge/intel/i82801gx/i82801gx.h 2009-03-11 14:48:20 UTC (rev 3990) +++ trunk/coreboot-v2/src/southbridge/intel/i82801gx/i82801gx.h 2009-03-11 14:54:18 UTC (rev 3991) @@ -1,12 +1,12 @@ /* * This file is part of the coreboot project. * - * Copyright (C) 2008 coresystems GmbH + * Copyright (C) 2008-2009 coresystems GmbH * - * 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 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; version 2 of + * the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of
Modified: trunk/coreboot-v2/src/southbridge/intel/i82801gx/i82801gx_ac97.c =================================================================== --- trunk/coreboot-v2/src/southbridge/intel/i82801gx/i82801gx_ac97.c 2009-03-11 14:48:20 UTC (rev 3990) +++ trunk/coreboot-v2/src/southbridge/intel/i82801gx/i82801gx_ac97.c 2009-03-11 14:54:18 UTC (rev 3991) @@ -3,10 +3,10 @@ * * Copyright (C) 2008-2009 coresystems GmbH * - * 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 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; version 2 of + * the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -119,7 +119,6 @@
static void ac97_audio_init(struct device *dev) { - u8 reg8; u16 reg16; u32 reg32; int i;
Modified: trunk/coreboot-v2/src/southbridge/intel/i82801gx/i82801gx_azalia.c =================================================================== --- trunk/coreboot-v2/src/southbridge/intel/i82801gx/i82801gx_azalia.c 2009-03-11 14:48:20 UTC (rev 3990) +++ trunk/coreboot-v2/src/southbridge/intel/i82801gx/i82801gx_azalia.c 2009-03-11 14:54:18 UTC (rev 3991) @@ -31,61 +31,63 @@ #define HDA_ICII_BUSY (1 << 0) #define HDA_ICII_VALID (1 << 1)
+typedef struct southbridge_intel_i82801gx_config config_t; + static int set_bits(u8 * port, u32 mask, u32 val) { - u32 dword; + u32 reg32; int count;
+ /* Write (val & mask) to port */ val &= mask; - dword = readl(port); - dword &= ~mask; - dword |= val; - writel(dword, port); + reg32 = readl(port); + reg32 &= ~mask; + reg32 |= val; + writel(reg32, port);
+ /* Wait for readback of register to + * match what was just written to it + */ count = 50; do { - dword = readl(port); - dword &= mask; - udelay(100); - } while ((dword != val) && --count); + /* Wait 1ms based on BKDG wait time */ + mdelay(1); + reg32 = readl(port); + reg32 &= mask; + } while ((reg32 != val) && --count);
+ /* Timeout occured */ if (!count) return -1; - - udelay(540); return 0; }
static int codec_detect(u8 * base) { - u32 dword; + u32 reg32;
- /* 1 */ - set_bits(base + 0x08, 1, 1); + /* Set Bit0 to 0 to enter reset state (BAR + 0x8)[0] */ + if (set_bits(base + 0x08, 1, 0) == -1) + goto no_codec;
- /* 2 */ - dword = readl(base + 0x0e); - dword |= 7; - writel(dword, base + 0x0e); + /* Set Bit 0 to 1 to exit reset state (BAR + 0x8)[0] */ + if (set_bits(base + 0x08, 1, 1) == -1) + goto no_codec;
- /* 3 */ + /* Read in Codec location (BAR + 0xe)[2..0]*/ + reg32 = readl(base + 0xe); + reg32 &= 0x0f; + if (!reg32) + goto no_codec; + + return reg32; + +no_codec: + /* Codec Not found */ + /* Put HDA back in reset (BAR + 0x8) [0] */ 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; - + printk_debug("Azalia: No codec!\n"); + return 0; }
static u32 cim_verb_data[] = { @@ -156,19 +158,24 @@ 0x01F71F41, };
-static unsigned find_verb(u32 viddid, u32 ** verb) +static unsigned find_verb(struct device *dev, u32 viddid, u32 ** verb) { - device_t azalia_dev = dev_find_slot(0, PCI_DEVFN(0x14, 2)); - struct southbridge_intel_i82801gx_config *cfg = - (struct southbridge_intel_i82801gx_config *)azalia_dev->chip_info; - printk_debug("Dev=%s\n", dev_path(azalia_dev)); - printk_debug("Default viddid=%x\n", cfg->hda_viddid); - printk_debug("Reading viddid=%x\n", viddid); - if (!cfg) + config_t *config = dev->chip_info; + + if (config == NULL) { + printk_err("\ni82801gx_azalia: Not mentioned in mainboard's Config.lb!\n"); return 0; - if (viddid != cfg->hda_viddid) + } + + printk_debug("Azalia: dev=%s\n", dev_path(dev)); + printk_debug("Azalia: Default viddid=%x\n", (u32)config->hda_viddid); + printk_debug("Azalia: Reading viddid=%x\n", viddid); + + if (viddid != config->hda_viddid) return 0; + *verb = (u32 *) cim_verb_data; + return sizeof(cim_verb_data) / sizeof(u32); }
@@ -185,8 +192,8 @@ int timeout = 50;
while(timeout--) { - u32 dword=readl(base + HDA_ICII_REG); - if (!(dword & HDA_ICII_BUSY)) + u32 reg32 = readl(base + HDA_ICII_REG); + if (!(reg32 & HDA_ICII_BUSY)) return 0; udelay(1); } @@ -207,8 +214,8 @@
int timeout = 50; while(timeout--) { - u32 dword = readl(base + HDA_ICII_REG); - if ((dword & (HDA_ICII_VALID | HDA_ICII_BUSY)) == + u32 reg32 = readl(base + HDA_ICII_REG); + if ((reg32 & (HDA_ICII_VALID | HDA_ICII_BUSY)) == HDA_ICII_VALID) return 0; udelay(1); @@ -217,9 +224,9 @@ return 1; }
-static void codec_init(u8 * base, int addr) +static void codec_init(struct device *dev, u8 * base, int addr) { - u32 dword; + u32 reg32; u32 *verb; u32 verb_size; int i; @@ -228,24 +235,24 @@ if (wait_for_ready(base) == -1) return;
- dword = (addr << 28) | 0x000f0000; - writel(dword, base + 0x60); + reg32 = (addr << 28) | 0x000f0000; + writel(reg32, base + 0x60);
if (wait_for_valid(base) == -1) return;
- dword = readl(base + 0x64); + reg32 = readl(base + 0x64);
/* 2 */ - printk_debug("codec viddid: %08x\n", dword); - verb_size = find_verb(dword, &verb); + printk_debug("Azalia: codec viddid: %08x\n", reg32); + verb_size = find_verb(dev, reg32, &verb);
if (!verb_size) { - printk_debug("No verb!\n"); + printk_debug("Azalia: No verb!\n"); return; }
- printk_debug("verb_size: %d\n", verb_size); + printk_debug("Azalia: verb_size: %d\n", verb_size); /* 3 */ for (i = 0; i < verb_size; i++) { if (wait_for_ready(base) == -1) @@ -256,15 +263,15 @@ if (wait_for_valid(base) == -1) return; } - printk_debug("verb loaded!\n"); + printk_debug("Azalia: verb loaded.\n"); }
-static void codecs_init(u8 * base, u32 codec_mask) +static void codecs_init(struct device *dev, u8 * base, u32 codec_mask) { int i; for (i = 2; i >= 0; i--) { if (codec_mask & (1 << i)) - codec_init(base, i); + codec_init(dev, base, i); } }
@@ -273,7 +280,71 @@ u8 *base; struct resource *res; u32 codec_mask; + u8 reg8; + u32 reg32;
+#if MMCONF_SUPPORT + // ESD + reg32 = pci_mmio_read_config32(dev, 0x134); + reg32 &= 0xff00ffff; + reg32 |= (2 << 16); + pci_mmio_write_config32(dev, 0x134, reg32); + + // Link1 description + reg32 = pci_mmio_read_config32(dev, 0x140); + reg32 &= 0xff00ffff; + reg32 |= (2 << 16); + pci_mmio_write_config32(dev, 0x140, reg32); + + // Port VC0 Resource Control Register + reg32 = pci_mmio_read_config32(dev, 0x114); + reg32 &= 0xffffff00; + reg32 |= 1; + pci_mmio_write_config32(dev, 0x114, reg32); + + // VCi traffic class + reg8 = pci_mmio_read_config8(dev, 0x44); + reg8 |= (7 << 0); // TC7 + pci_mmio_write_config8(dev, 0x44, reg8); + + // VCi Resource Control + reg32 = pci_mmio_read_config32(dev, 0x120); + reg32 |= (1 << 31); + reg32 |= (1 << 24); // VCi ID + reg32 |= (0x80 << 0); // VCi map + pci_mmio_write_config32(dev, 0x120, reg32); +#else +#error ICH7 Azalia required MMCONF_SUPPORT +#endif + + /* Set Bus Master */ + reg32 = pci_read_config32(dev, PCI_COMMAND); + pci_write_config32(dev, PCI_COMMAND, reg32 | PCI_COMMAND_MASTER); + + pci_write_config8(dev, 0x3c, 0x0a); // unused? + + // TODO Actually check if we're AC97 or HDA instead of hardcoding this + // here, in Config.lb and/or auto.c. + reg8 = pci_read_config8(dev, 0x40); + reg8 |= (1 << 3); // Clear Clock Detect Bit + pci_write_config8(dev, 0x40, reg8); + reg8 &= ~(1 << 3); // Keep CLKDETCLR from clearing the bit over and over + pci_write_config8(dev, 0x40, reg8); + reg8 |= (1 << 2); // Enable clock detection + pci_write_config8(dev, 0x40, reg8); + mdelay(1); + reg8 = pci_read_config8(dev, 0x40); + printk_debug("Azalia: codec type: %s\n", (reg8 & (1 << 1))?"Azalia":"AC97"); + + // + reg8 = pci_read_config8(dev, 0x40); // Audio Control + reg8 |= 1; // Select Azalia mode. This needs to be controlled via Config.lb + pci_write_config8(dev, 0x40, reg8); + + reg8 = pci_read_config8(dev, 0x4d); // Docking Status + reg8 &= ~(1 << 7); // Docking not supported + pci_write_config8(dev, 0x4d, reg8); +#if 0 /* Set routing pin */ pci_write_config32(dev, 0xf8, 0x0); pci_write_config8(dev, 0xfc, 0xAA); @@ -283,21 +354,39 @@
/* Enable azalia, disable ac97 */ // pm_iowrite(0x59, 0xB); +#endif
res = find_resource(dev, 0x10); if (!res) return;
+ // NOTE this will break as soon as the Azalia get's a bar above + // 4G. Is there anything we can do about it? base = (u8 *) ((u32)res->base); - printk_debug("base = %08x\n", base); + printk_debug("Azalia: base = %08x\n", (u32)base); codec_mask = codec_detect(base);
if (codec_mask) { - printk_debug("codec_mask = %02x\n", codec_mask); - codecs_init(base, codec_mask); + printk_debug("Azalia: codec_mask = %02x\n", codec_mask); + codecs_init(dev, base, codec_mask); } }
+static void azalia_set_subsystem(device_t dev, unsigned vendor, unsigned device) +{ + if (!vendor || !device) { + pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID, + pci_read_config32(dev, PCI_VENDOR_ID)); + } else { + pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID, + ((device & 0xffff) << 16) | (vendor & 0xffff)); + } +} + +static struct pci_operations azalia_pci_ops = { + .set_subsystem = azalia_set_subsystem, +}; + static struct device_operations azalia_ops = { .read_resources = pci_dev_read_resources, .set_resources = pci_dev_set_resources, @@ -305,6 +394,7 @@ .init = azalia_init, .scan_bus = 0, .enable = i82801gx_enable, + .ops_pci = &azalia_pci_ops, };
/* 82801GB/GR/GDH/GBM/GHM (ICH7/ICH7R/ICH7DH/ICH7-M/ICH7-M DH) */
Modified: trunk/coreboot-v2/src/southbridge/intel/i82801gx/i82801gx_early_smbus.c =================================================================== --- trunk/coreboot-v2/src/southbridge/intel/i82801gx/i82801gx_early_smbus.c 2009-03-11 14:48:20 UTC (rev 3990) +++ trunk/coreboot-v2/src/southbridge/intel/i82801gx/i82801gx_early_smbus.c 2009-03-11 14:54:18 UTC (rev 3991) @@ -1,12 +1,12 @@ /* * This file is part of the coreboot project. * - * Copyright (C) 2008 coresystems GmbH + * Copyright (C) 2008-2009 coresystems GmbH * - * 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 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; version 2 of + * the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -54,6 +54,6 @@
static inline int smbus_read_byte(unsigned device, unsigned address) { - return do_smbus_read_byte(device, address); + return do_smbus_read_byte(SMBUS_IO_BASE, device, address); }
Modified: trunk/coreboot-v2/src/southbridge/intel/i82801gx/i82801gx_ide.c =================================================================== --- trunk/coreboot-v2/src/southbridge/intel/i82801gx/i82801gx_ide.c 2009-03-11 14:48:20 UTC (rev 3990) +++ trunk/coreboot-v2/src/southbridge/intel/i82801gx/i82801gx_ide.c 2009-03-11 14:54:18 UTC (rev 3991) @@ -1,12 +1,12 @@ /* * This file is part of the coreboot project. * - * Copyright (C) 2008 coresystems GmbH + * Copyright (C) 2008-2009 coresystems GmbH * - * 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 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; version 2 of + * the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -30,12 +30,20 @@ { u16 ideTimingConfig; u32 reg32; + u32 enable_primary, enable_secondary;
/* Get the chip configuration */ config_t *config = dev->chip_info;
- int enable_primary = config->ide_enable_primary; - int enable_secondary = config->ide_enable_secondary; + printk_debug("i82801gx_ide: initializing... "); + if (config == NULL) { + printk_err("\ni82801gx_ide: Not mentioned in mainboard's Config.lb!\n"); + // Trying to set somewhat save defaults instead of bailing out. + enable_primary = enable_secondary = 1; + } else { + enable_primary = config->ide_enable_primary; + enable_secondary = config->ide_enable_secondary; + }
reg32 = pci_read_config32(dev, PCI_COMMAND); pci_write_config32(dev, PCI_COMMAND, reg32 | PCI_COMMAND_IO | PCI_COMMAND_MASTER); @@ -81,8 +89,25 @@ /* Set Interrupt Line */ /* Interrupt Pin is set by D31IP.PIP */ pci_write_config32(dev, INTR_LN, 0xff); /* Int 15 */ + + printk_debug("\n"); }
+static void ide_set_subsystem(device_t dev, unsigned vendor, unsigned device) +{ + if (!vendor || !device) { + pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID, + pci_read_config32(dev, PCI_VENDOR_ID)); + } else { + pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID, + ((device & 0xffff) << 16) | (vendor & 0xffff)); + } +} + +static struct pci_operations ide_pci_ops = { + .set_subsystem = ide_set_subsystem, +}; + static struct device_operations ide_ops = { .read_resources = pci_dev_read_resources, .set_resources = pci_dev_set_resources, @@ -90,6 +115,7 @@ .init = ide_init, .scan_bus = 0, .enable = i82801gx_enable, + .ops_pci = &ide_pci_ops, };
/* 82801GB/GR/GDH/GBM/GHM/GU (ICH7/ICH7R/ICH7DH/ICH7-M/ICH7-M DH/ICH7-U) */
Modified: trunk/coreboot-v2/src/southbridge/intel/i82801gx/i82801gx_lpc.c =================================================================== --- trunk/coreboot-v2/src/southbridge/intel/i82801gx/i82801gx_lpc.c 2009-03-11 14:48:20 UTC (rev 3990) +++ trunk/coreboot-v2/src/southbridge/intel/i82801gx/i82801gx_lpc.c 2009-03-11 14:54:18 UTC (rev 3991) @@ -3,10 +3,10 @@ * * Copyright (C) 2008-2009 coresystems GmbH * - * 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 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; version 2 of + * the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -151,6 +151,35 @@ } }
+static void i82801gx_gpi_routing(device_t dev) +{ + /* Get the chip configuration */ + config_t *config = dev->chip_info; + u32 reg32 = 0; + + /* An array would be much nicer here, or some + * other method of doing this. + */ + reg32 |= (config->gpi0_routing & 0x03) << 0; + reg32 |= (config->gpi1_routing & 0x03) << 2; + reg32 |= (config->gpi2_routing & 0x03) << 4; + reg32 |= (config->gpi3_routing & 0x03) << 6; + reg32 |= (config->gpi4_routing & 0x03) << 8; + reg32 |= (config->gpi5_routing & 0x03) << 10; + reg32 |= (config->gpi6_routing & 0x03) << 12; + reg32 |= (config->gpi7_routing & 0x03) << 14; + reg32 |= (config->gpi8_routing & 0x03) << 16; + reg32 |= (config->gpi9_routing & 0x03) << 18; + reg32 |= (config->gpi10_routing & 0x03) << 20; + reg32 |= (config->gpi11_routing & 0x03) << 22; + reg32 |= (config->gpi12_routing & 0x03) << 24; + reg32 |= (config->gpi13_routing & 0x03) << 26; + reg32 |= (config->gpi14_routing & 0x03) << 28; + reg32 |= (config->gpi15_routing & 0x03) << 30; + + pci_write_config32(dev, 0xb8, reg32); +} + static void i82801gx_power_options(device_t dev) { u8 reg8; @@ -172,6 +201,7 @@ reg8 |= 1; } reg8 |= (3 << 4); /* avoid #S4 assertions */ + reg8 &= ~(1 << 3); /* minimum asssertion is 1 to 2 RTCCLK */
pci_write_config8(dev, GEN_PMCON_3, reg8); printk_info("Set power %s after power failure.\n", pwr_on ? "on" : "off"); @@ -198,19 +228,34 @@
// Enable CPU_SLP# and Intel Speedstep, set SMI# rate down reg16 = pci_read_config16(dev, GEN_PMCON_1); - reg16 &= ~3; - reg16 |= (1 << 3) | (1 << 5) | (1 << 10); + reg16 &= ~((3 << 0) | (1 << 10)); + reg16 |= (1 << 3) | (1 << 5); + reg16 |= (1 << 2); // CLKRUN_EN pci_write_config16(dev, GEN_PMCON_1, reg16);
- // Set GPIO13 to SCI (?) - // This might be board specific - pci_write_config32(dev, 0xb8, 0x08000000); + // Set the board's GPI routing. + i82801gx_gpi_routing(dev); }
-void i82801gx_rtc_init(struct device *dev) +static void i82801gx_configure_cstates(device_t dev) { u8 reg8; - u32 reg32; + + reg8 = pci_read_config8(dev, 0xa9); // Cx state configuration + reg8 |= (1 << 4) | (1 << 3) | (1 << 2); // Enable Popup & Popdown + pci_write_config8(dev, 0xa9, reg8); + + // Set Deeper Sleep configuration to recommended values + reg8 = pci_read_config8(dev, 0xaa); + reg8 &= 0xf0; + reg8 |= (2 << 2); // Deeper Sleep to Stop CPU: 34-40us + reg8 |= (2 << 0); // Deeper Sleep to Sleep: 15us + pci_write_config8(dev, 0xaa, reg8); +} + +static void i82801gx_rtc_init(struct device *dev) +{ + u8 reg8; int rtc_failed;
reg8 = pci_read_config8(dev, GEN_PMCON_3); @@ -224,17 +269,40 @@ rtc_init(rtc_failed); }
-static void enable_hpet(struct device *dev) +static void enable_hpet(void) { - /* TODO */ + u32 reg32; + + /* Leave HPET at default address, but enable it */ + reg32 = RCBA32(0x3404); + reg32 |= (1 << 7); // HPET Address Enable + RCBA32(0x3404) = reg32; }
+static void enable_clock_gating(void) +{ + u32 reg32; + + /* Enable Clock Gating for most devices */ + reg32 = RCBA32(0x341c); + reg32 |= (1 << 31); // LPC clock gating + reg32 |= (1 << 30); // PATA clock gating + // SATA clock gating + reg32 |= (1 << 27) | (1 << 26) | (1 << 25) | (1 << 24); + reg32 |= (1 << 23); // AC97 clock gating + reg32 |= (1 << 20) | (1 << 19); // USB EHCI clock gating + reg32 |= (1 << 3) | (1 << 1); // DMI clock gating + reg32 |= (1 << 2); // PCIe clock gating; + RCBA32(0x341c) = reg32; +}
#if HAVE_SMI_HANDLER static void i82801gx_lock_smm(struct device *dev) { void smm_lock(void); +#if TEST_SMM_FLASH_LOCKDOWN u8 reg8; +#endif
#if ENABLE_ACPI_MODE_IN_COREBOOT printk_debug("Enabling ACPI via APMC:\n"); @@ -279,6 +347,22 @@ } #endif
+#define SPIBASE 0x3020 +static void i82801gx_spi_init(void) +{ + u16 spicontrol; + + spicontrol = RCBA16(SPIBASE + 2); + spicontrol &= ~(1 << 0); // SPI Access Request + RCBA16(SPIBASE + 2) = spicontrol; +} + +static void i82801gx_fixups(void) +{ + /* This needs to happen after PCI enumeration */ + RCBA32(0x1d40) |= 1; +} + static void lpc_init(struct device *dev) { printk_debug("i82801gx: lpc_init\n"); @@ -297,6 +381,9 @@ /* Setup power options. */ i82801gx_power_options(dev);
+ /* Configure Cx state registers */ + i82801gx_configure_cstates(dev); + /* Set the state of the GPIO lines. */ //gpio_init(dev);
@@ -307,13 +394,20 @@ isa_dma_init();
/* Initialize the High Precision Event Timers, if present. */ - enable_hpet(dev); + enable_hpet();
+ /* Initialize Clock Gating */ + enable_clock_gating(); + setup_i8259();
#if HAVE_SMI_HANDLER i82801gx_lock_smm(dev); #endif + + i82801gx_spi_init(); + + i82801gx_fixups(); }
static void i82801gx_lpc_read_resources(device_t dev) @@ -341,9 +435,13 @@
static void set_subsystem(device_t dev, unsigned vendor, unsigned device) { - printk_debug("Setting LPC bridge subsystem ID\n"); - pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID, - pci_read_config32(dev, 0)); + if (!vendor || !device) { + pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID, + pci_read_config32(dev, PCI_VENDOR_ID)); + } else { + pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID, + ((device & 0xffff) << 16) | (vendor & 0xffff)); + } }
static struct pci_operations pci_ops = {
Modified: trunk/coreboot-v2/src/southbridge/intel/i82801gx/i82801gx_nic.c =================================================================== --- trunk/coreboot-v2/src/southbridge/intel/i82801gx/i82801gx_nic.c 2009-03-11 14:48:20 UTC (rev 3990) +++ trunk/coreboot-v2/src/southbridge/intel/i82801gx/i82801gx_nic.c 2009-03-11 14:54:18 UTC (rev 3991) @@ -1,12 +1,12 @@ /* * This file is part of the coreboot project. * - * Copyright (C) 2008 coresystems GmbH + * Copyright (C) 2008-2009 coresystems GmbH * - * 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 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; version 2 of + * the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of
Modified: trunk/coreboot-v2/src/southbridge/intel/i82801gx/i82801gx_pci.c =================================================================== --- trunk/coreboot-v2/src/southbridge/intel/i82801gx/i82801gx_pci.c 2009-03-11 14:48:20 UTC (rev 3990) +++ trunk/coreboot-v2/src/southbridge/intel/i82801gx/i82801gx_pci.c 2009-03-11 14:54:18 UTC (rev 3991) @@ -3,10 +3,10 @@ * * Copyright (C) 2008-2009 coresystems GmbH * - * 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 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; version 2 of + * the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -26,31 +26,42 @@ static void pci_init(struct device *dev) { u16 reg16; + u8 reg8;
-#if 0 - /* Commented out for now because it will break on some machines. */ - /* Set latency timer to 32. */ - pci_write_config16(dev, 0x1b, 0x20); -#endif + /* Enable Bus Master */ + reg16 = pci_read_config16(dev, PCI_COMMAND); + reg16 |= PCI_COMMAND_MASTER; + pci_write_config16(dev, PCI_COMMAND, reg16);
- /* disable parity error response */ + /* This device has no interrupt */ + pci_write_config8(dev, 0x3c, 0xff); + + /* disable parity error response and SERR */ reg16 = pci_read_config16(dev, 0x3e); reg16 &= ~(1 << 0); + reg16 &= ~(1 << 1); pci_write_config16(dev, 0x3e, reg16);
+ /* Master Latency Count must be set to 0x04! */ + reg8 = pci_read_config8(dev, 0x1b); + reg8 &= 0x07; + reg8 |= (0x04 << 3); + pci_write_config8(dev, 0x1b, reg8); + + /* Will this improve throughput of bus masters? */ + pci_write_config8(dev, PCI_MIN_GNT, 0x06); + /* Clear errors in status registers */ reg16 = pci_read_config16(dev, 0x06); - reg16 |= 0xf900; + //reg16 |= 0xf900; pci_write_config16(dev, 0x06, reg16);
reg16 = pci_read_config16(dev, 0x1e); - reg16 |= 0xf900; + // reg16 |= 0xf900; pci_write_config16(dev, 0x1e, reg16); - - /* Will this improve throughput of bus masters? */ - pci_write_config8(dev, PCI_MIN_GNT, 0x06); }
+#undef PCI_BRIDGE_UPDATE_COMMAND static void ich_pci_dev_enable_resources(struct device *dev) { const struct pci_operations *ops; @@ -68,15 +79,17 @@ MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID); }
-#if 0 + command = pci_read_config16(dev, PCI_COMMAND); + command |= dev->command; +#if PCI_BRIDGE_UPDATE_COMMAND /* If we write to PCI_COMMAND, on some systems * this will cause the ROM and APICs not being visible * anymore. */ - command = pci_read_config16(dev, PCI_COMMAND); - command |= dev->command; printk_debug("%s cmd <- %02x\n", dev_path(dev), command); pci_write_config16(dev, PCI_COMMAND, command); +#else + printk_debug("%s cmd <- %02x (NOT WRITTEN!)\n", dev_path(dev), command); #endif }
@@ -102,16 +115,14 @@
static void set_subsystem(device_t dev, unsigned vendor, unsigned device) { -#if 0 - /* Currently disabled because it causes a "BAR 9" memory resource - * conflict: - */ - u32 pci_id; - - printk_debug("Setting PCI bridge subsystem ID\n"); - pci_id = pci_read_config32(dev, 0); - pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID, pci_id ); -#endif + /* NOTE: This is not the default position! */ + if (!vendor || !device) { + pci_write_config32(dev, 0x54, + pci_read_config32(dev, PCI_VENDOR_ID)); + } else { + pci_write_config32(dev, 0x54, + ((device & 0xffff) << 16) | (vendor & 0xffff)); + } }
static struct pci_operations pci_ops = {
Modified: trunk/coreboot-v2/src/southbridge/intel/i82801gx/i82801gx_pcie.c =================================================================== --- trunk/coreboot-v2/src/southbridge/intel/i82801gx/i82801gx_pcie.c 2009-03-11 14:48:20 UTC (rev 3990) +++ trunk/coreboot-v2/src/southbridge/intel/i82801gx/i82801gx_pcie.c 2009-03-11 14:54:18 UTC (rev 3991) @@ -3,10 +3,10 @@ * * Copyright (C) 2008-2009 coresystems GmbH * - * 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 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; version 2 of + * the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -29,29 +29,53 @@ u32 reg32;
printk_debug("Initializing ICH7 PCIe bridge.\n"); -#if 0 - // When the latency of the PCIe(!) bridge is set to 0x20 - // all devices on the secondary bus of the PCI(!) bridge - // suddenly vanish. If you know why, please explain here. + + /* Enable Bus Master */ + reg32 = pci_read_config32(dev, PCI_COMMAND); + reg32 |= PCI_COMMAND_MASTER; + pci_write_config32(dev, PCI_COMMAND, reg32);
- /* Set latency timer to 32. */ - pci_write_config16(dev, 0x1b, 0x20); -#endif + /* Set Cache Line Size to 0x10 */ + // This has no effect but the OS might expect it + pci_write_config8(dev, 0x0c, 0x10);
- /* disable parity error response */ reg16 = pci_read_config16(dev, 0x3e); - reg16 &= ~(1 << 0); + reg16 &= ~(1 << 0); /* disable parity error response */ + // reg16 &= ~(1 << 1); /* disable SERR */ + reg16 |= (1 << 2); /* ISA enable */ pci_write_config16(dev, 0x3e, reg16);
- /* Clear errors in status registers */ - reg16 = pci_read_config16(dev, 0x06); - reg16 |= 0xf900; - pci_write_config16(dev, 0x06, reg16); + /* Enable IO xAPIC on this PCIe port */ + reg32 = pci_read_config32(dev, 0xd8); + reg32 |= (1 << 7); + pci_write_config32(dev, 0xd8, reg32);
- reg16 = pci_read_config16(dev, 0x1e); - reg16 |= 0xf900; - pci_write_config16(dev, 0x1e, reg16); + /* Enable Backbone Clock Gating */ + reg32 = pci_read_config32(dev, 0xe1); + reg32 |= (1 << 3) | (1 << 2) | (1 << 1) | (1 << 0); + pci_write_config32(dev, 0xe1, reg32);
+#if MMCONF_SUPPORT + /* Set VC0 transaction class */ + reg32 = pci_mmio_read_config32(dev, 0x114); + reg32 &= 0xffffff00; + reg32 |= 1; + pci_mmio_write_config32(dev, 0x114, reg32); + + /* Mask completion timeouts */ + reg32 = pci_mmio_read_config32(dev, 0x148); + reg32 |= (1 << 14); + pci_mmio_write_config32(dev, 0x148, reg32); +#else +#error "MMIO needed for ICH7 PCIe" +#endif + /* Enable common clock configuration */ + // Are there cases when we don't want that? + reg16 = pci_read_config16(dev, 0x50); + reg16 |= (1 << 6); + pci_write_config16(dev, 0x50, reg16); + +#if EVEN_MORE_DEBUG reg32 = pci_read_config32(dev, 0x20); printk_spew(" MBL = 0x%08x\n", reg32); reg32 = pci_read_config32(dev, 0x24); @@ -60,19 +84,32 @@ printk_spew(" PMBU32 = 0x%08x\n", reg32); reg32 = pci_read_config32(dev, 0x2c); printk_spew(" PMLU32 = 0x%08x\n", reg32); +#endif + + /* Clear errors in status registers */ + reg16 = pci_read_config16(dev, 0x06); + //reg16 |= 0xf900; + pci_write_config16(dev, 0x06, reg16); + + reg16 = pci_read_config16(dev, 0x1e); + //reg16 |= 0xf900; + pci_write_config16(dev, 0x1e, reg16); }
-static void set_subsystem(device_t dev, unsigned vendor, unsigned device) +static void pcie_set_subsystem(device_t dev, unsigned vendor, unsigned device) { - u32 pci_id; - - printk_debug("Setting PCIe bridge subsystem ID.\n"); - pci_id = pci_read_config32(dev, 0); - pci_write_config32(dev, 0x94, pci_id ); + /* NOTE: This is not the default position! */ + if (!vendor || !device) { + pci_write_config32(dev, 0x94, + pci_read_config32(dev, 0)); + } else { + pci_write_config32(dev, 0x94, + ((device & 0xffff) << 16) | (vendor & 0xffff)); + } }
static struct pci_operations pci_ops = { - .set_subsystem = set_subsystem, + .set_subsystem = pcie_set_subsystem, };
static struct device_operations device_ops = {
Modified: trunk/coreboot-v2/src/southbridge/intel/i82801gx/i82801gx_reset.c =================================================================== --- trunk/coreboot-v2/src/southbridge/intel/i82801gx/i82801gx_reset.c 2009-03-11 14:48:20 UTC (rev 3990) +++ trunk/coreboot-v2/src/southbridge/intel/i82801gx/i82801gx_reset.c 2009-03-11 14:54:18 UTC (rev 3991) @@ -1,12 +1,12 @@ /* * This file is part of the coreboot project. * - * Copyright (C) 2008 coresystems GmbH + * Copyright (C) 2008-2009 coresystems GmbH * - * 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 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; version 2 of + * the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of
Modified: trunk/coreboot-v2/src/southbridge/intel/i82801gx/i82801gx_sata.c =================================================================== --- trunk/coreboot-v2/src/southbridge/intel/i82801gx/i82801gx_sata.c 2009-03-11 14:48:20 UTC (rev 3990) +++ trunk/coreboot-v2/src/southbridge/intel/i82801gx/i82801gx_sata.c 2009-03-11 14:54:18 UTC (rev 3991) @@ -3,10 +3,10 @@ * * Copyright (C) 2008-2009 coresystems GmbH * - * 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 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; version 2 of + * the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -29,16 +29,29 @@ static void sata_init(struct device *dev) { u32 reg32; + u16 reg16; /* Get the chip configuration */ config_t *config = dev->chip_info;
printk_debug("i82801gx_sata: initializing...\n"); + + if (config == NULL) + printk_err("i82801gx_sata: error: device not in Config.lb!\n"); + /* SATA configuration */
/* Enable BARs */ - pci_write_config16(dev, 0x04, 0x0007); + pci_write_config16(dev, PCI_COMMAND, 0x0007);
if (config->ide_legacy_combined) { + printk_debug("SATA controller in combined mode.\n"); + /* No AHCI: clear AHCI base */ + pci_write_config32(dev, 0x24, 0x00000000); + /* And without AHCI BAR no memory decoding */ + reg16 = pci_read_config16(dev, PCI_COMMAND); + reg16 &= ~PCI_COMMAND_MEMORY; + pci_write_config16(dev, PCI_COMMAND, reg16); + pci_write_config8(dev, 0x09, 0x80);
/* Set timings */ @@ -49,6 +62,10 @@ pci_write_config16(dev, 0x48, 0x0004); pci_write_config16(dev, 0x4a, 0x0200);
+ /* Set IDE I/O Configuration */ + reg32 = SIG_MODE_NORMAL | FAST_PCB1 | FAST_PCB0 | PCB1 | PCB0; + pci_write_config32(dev, IDE_CONFIG, reg32); + /* Combine IDE - SATA configuration */ pci_write_config8(dev, 0x90, 0x02);
@@ -56,8 +73,9 @@ pci_write_config8(dev, 0x92, 0x0f);
/* SATA Initialization register */ - pci_write_config32(dev, 0x94, 0x40000180); + pci_write_config32(dev, 0x94, 0x5a000180); } else if(config->sata_ahci) { + printk_debug("SATA controller in AHCI mode.\n"); /* Allow both Legacy and Native mode */ pci_write_config8(dev, 0x09, 0x8f);
@@ -86,6 +104,18 @@ /* SATA Initialization register */ pci_write_config32(dev, 0x94, 0x1a000180); } else { + printk_debug("SATA controller in plain mode.\n"); + /* Set Sata Controller Mode. No Mapping(?) */ + pci_write_config8(dev, 0x90, 0x00); + + /* No AHCI: clear AHCI base */ + pci_write_config32(dev, 0x24, 0x00000000); + + /* And without AHCI BAR no memory decoding */ + reg16 = pci_read_config16(dev, PCI_COMMAND); + reg16 &= ~PCI_COMMAND_MEMORY; + pci_write_config16(dev, PCI_COMMAND, reg16); + /* Native mode capable on both primary and secondary (0xa) * or'ed with enabled (0x50) = 0xf */ @@ -107,9 +137,6 @@ reg32 = SIG_MODE_NORMAL | FAST_PCB1 | FAST_PCB0 | PCB1 | PCB0; pci_write_config32(dev, IDE_CONFIG, reg32); - /* Set Sata Controller Mode. */ - pci_write_config8(dev, 0x90, 0x02); - /* Port 0 & 1 enable XXX */ pci_write_config8(dev, 0x92, 0x15); @@ -135,8 +162,28 @@ pci_write_config8(dev, 0xa0, 0x00);
pci_write_config8(dev, PCI_INTERRUPT_LINE, 0); + + /* Sata Initialization Register */ + reg32 = pci_read_config32(dev, 0x94); + reg32 |= (1 << 30); // due to some bug + pci_write_config32(dev, 0x94, reg32); }
+static void sata_set_subsystem(device_t dev, unsigned vendor, unsigned device) +{ + if (!vendor || !device) { + pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID, + pci_read_config32(dev, PCI_VENDOR_ID)); + } else { + pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID, + ((device & 0xffff) << 16) | (vendor & 0xffff)); + } +} + +static struct pci_operations sata_pci_ops = { + .set_subsystem = sata_set_subsystem, +}; + static struct device_operations sata_ops = { .read_resources = pci_dev_read_resources, .set_resources = pci_dev_set_resources, @@ -144,6 +191,7 @@ .init = sata_init, .scan_bus = 0, .enable = i82801gx_enable, + .ops_pci = &sata_pci_ops, };
/* Desktop Non-AHCI and Non-RAID Mode */ @@ -154,6 +202,15 @@ .device = 0x27c0, };
+/* Mobile Non-AHCI and Non-RAID Mode */ +/* 82801GBM/GHM (ICH7-M/ICH7-M DH) */ +static const struct pci_driver i82801gx_sata_mobile_normal_driver __pci_driver = { + .ops = &sata_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .device = 0x27c4, +}; + + /* NOTE: Any of the below are not properly supported yet. */
/* Desktop AHCI Mode */ @@ -172,14 +229,6 @@ .device = 0x27c3, };
-/* Mobile Non-AHCI and Non-RAID Mode */ -/* 82801GBM/GHM (ICH7-M/ICH7-M DH) */ -static const struct pci_driver i82801gx_sata_mobile_normal_driver __pci_driver = { - .ops = &sata_ops, - .vendor = PCI_VENDOR_ID_INTEL, - .device = 0x27c4, -}; - /* Mobile AHCI Mode */ /* 82801GBM/GHM (ICH7-M/ICH7-M DH) */ static const struct pci_driver i82801gx_sata_mobile_ahci_driver __pci_driver = {
Modified: trunk/coreboot-v2/src/southbridge/intel/i82801gx/i82801gx_smbus.c =================================================================== --- trunk/coreboot-v2/src/southbridge/intel/i82801gx/i82801gx_smbus.c 2009-03-11 14:48:20 UTC (rev 3990) +++ trunk/coreboot-v2/src/southbridge/intel/i82801gx/i82801gx_smbus.c 2009-03-11 14:54:18 UTC (rev 3991) @@ -1,12 +1,12 @@ /* * This file is part of the coreboot project. * - * Copyright (C) 2008 coresystems GmbH + * Copyright (C) 2008-2009 coresystems GmbH * - * 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 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; version 2 of + * the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -18,29 +18,49 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
-#include <stdint.h> -#include <smbus.h> -#include <pci.h> -#include <pci_ids.h> +#include <console/console.h> +#include <device/device.h> +#include <device/path.h> +#include <device/smbus.h> +#include <device/pci.h> +#include <device/pci_ids.h> +#include <device/pci_ops.h> #include <arch/io.h> #include "i82801gx.h" -#include "i82801_smbus.h" - -static int smbus_read_byte(struct bus *bus, device_t dev, u8 address) +#include "i82801gx_smbus.h" + +static int lsmbus_read_byte(device_t dev, u8 address) { u16 device; struct resource *res; + struct bus *pbus;
device = dev->path.i2c.device; - res = find_resource(bus->dev, 0x20); + pbus = get_pbus_smbus(dev); + res = find_resource(pbus->dev, 0x20);
return do_smbus_read_byte(res->base, device, address); }
static struct smbus_bus_operations lops_smbus_bus = { - .read_byte = smbus_read_byte, + .read_byte = lsmbus_read_byte, };
+static void smbus_set_subsystem(device_t dev, unsigned vendor, unsigned device) +{ + if (!vendor || !device) { + pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID, + pci_read_config32(dev, PCI_VENDOR_ID)); + } else { + pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID, + ((device & 0xffff) << 16) | (vendor & 0xffff)); + } +} + +static struct pci_operations smbus_pci_ops = { + .set_subsystem = smbus_set_subsystem, +}; + static struct device_operations smbus_ops = { .read_resources = pci_dev_read_resources, .set_resources = pci_dev_set_resources, @@ -49,6 +69,7 @@ .scan_bus = scan_static_bus, .enable = i82801gx_enable, .ops_smbus_bus = &lops_smbus_bus, + .ops_pci = &smbus_pci_ops, };
/* 82801GB/GR/GDH/GBM/GHM/GU (ICH7/ICH7R/ICH7DH/ICH7-M/ICH7-M DH/ICH7-U) */
Modified: trunk/coreboot-v2/src/southbridge/intel/i82801gx/i82801gx_smbus.h =================================================================== --- trunk/coreboot-v2/src/southbridge/intel/i82801gx/i82801gx_smbus.h 2009-03-11 14:48:20 UTC (rev 3990) +++ trunk/coreboot-v2/src/southbridge/intel/i82801gx/i82801gx_smbus.h 2009-03-11 14:54:18 UTC (rev 3991) @@ -2,11 +2,12 @@ * This file is part of the coreboot project. * * Copyright (C) 2005 Yinghai Lu yinghailu@gmail.com + * Copyright (C) 2009 coresystems GmbH * - * 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 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; version 2 of + * the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -25,7 +26,7 @@ inb(0x80); }
-static int smbus_wait_until_ready(void) +static int smbus_wait_until_ready(u16 smbus_base) { unsigned loops = SMBUS_TIMEOUT; unsigned char byte; @@ -33,12 +34,12 @@ smbus_delay(); if (--loops == 0) break; - byte = inb(SMBUS_IO_BASE + SMBHSTSTAT); + byte = inb(smbus_base + SMBHSTSTAT); } while (byte & 1); return loops ? 0 : -1; }
-static int smbus_wait_until_done(void) +static int smbus_wait_until_done(u16 smbus_base) { unsigned loops = SMBUS_TIMEOUT; unsigned char byte; @@ -46,142 +47,54 @@ smbus_delay(); if (--loops == 0) break; - byte = inb(SMBUS_IO_BASE + SMBHSTSTAT); + byte = inb(smbus_base + SMBHSTSTAT); } while ((byte & 1) || (byte & ~((1 << 6) | (1 << 0))) == 0); return loops ? 0 : -1; }
-static int smbus_wait_until_blk_done(void) +static int do_smbus_read_byte(unsigned smbus_base, unsigned device, unsigned address) { - 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 device, unsigned address) -{ unsigned char global_status_register; unsigned char byte;
- if (smbus_wait_until_ready() < 0) { + if (smbus_wait_until_ready(smbus_base) < 0) { return SMBUS_WAIT_UNTIL_READY_TIMEOUT; } /* Setup transaction */ /* Disable interrupts */ - outb(inb(SMBUS_IO_BASE + SMBHSTCTL) & (~1), SMBUS_IO_BASE + SMBHSTCTL); + outb(inb(smbus_base + SMBHSTCTL) & (~1), smbus_base + SMBHSTCTL); /* Set the device I'm talking too */ - outb(((device & 0x7f) << 1) | 1, SMBUS_IO_BASE + SMBXMITADD); + outb(((device & 0x7f) << 1) | 1, smbus_base + SMBXMITADD); /* Set the command/address... */ - outb(address & 0xff, SMBUS_IO_BASE + SMBHSTCMD); + outb(address & 0xff, smbus_base + SMBHSTCMD); /* Set up for a byte data read */ - outb((inb(SMBUS_IO_BASE + SMBHSTCTL) & 0xe3) | (0x2 << 2), - (SMBUS_IO_BASE + SMBHSTCTL)); + outb((inb(smbus_base + SMBHSTCTL) & 0xe3) | (0x2 << 2), + (smbus_base + SMBHSTCTL)); /* Clear any lingering errors, so the transaction will run */ - outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT); + outb(inb(smbus_base + SMBHSTSTAT), smbus_base + SMBHSTSTAT);
/* Clear the data byte... */ - outb(0, SMBUS_IO_BASE + SMBHSTDAT0); + outb(0, smbus_base + SMBHSTDAT0);
/* Start the command */ - outb((inb(SMBUS_IO_BASE + SMBHSTCTL) | 0x40), - SMBUS_IO_BASE + SMBHSTCTL); + outb((inb(smbus_base + SMBHSTCTL) | 0x40), + smbus_base + SMBHSTCTL);
/* Poll for transaction completion */ - if (smbus_wait_until_done() < 0) { + if (smbus_wait_until_done(smbus_base) < 0) { return SMBUS_WAIT_UNTIL_DONE_TIMEOUT; }
- global_status_register = inb(SMBUS_IO_BASE + SMBHSTSTAT); + global_status_register = inb(smbus_base + SMBHSTSTAT);
/* Ignore the "In Use" status... */ global_status_register &= ~(3 << 5);
/* Read results of transaction */ - byte = inb(SMBUS_IO_BASE + SMBHSTDAT0); + byte = inb(smbus_base + SMBHSTDAT0); if (global_status_register != (1 << 1)) { return SMBUS_ERROR; } return byte; }
-/* This function is neither used nor tested by me (Corey Osgood), the author -(Yinghai) probably tested/used it on i82801er */ -static int do_smbus_write_block(unsigned device, unsigned length, unsigned cmd, - unsigned data1, unsigned data2) -{ - unsigned char byte; - unsigned char stat; - int i; - -#if CONFIG_USE_PRINTK_IN_CAR - printk_err("Untested smbus_write_block called\r\n"); -#else - print_err("Untested smbus_write_block called\r\n"); -#endif - - /* Clear the PM timeout flags, SECOND_TO_STS */ - outw(inw(0x0400 + 0x66), 0x0400 + 0x66); - - if (smbus_wait_until_ready() < 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; i < length; i++) { - - /* Poll for transaction completion */ - if (smbus_wait_until_blk_done() < 0) { - return -3; - } - - /* Load the next byte */ - if (i > 3) - 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); - } - -#if CONFIG_USE_PRINTK_IN_CAR - printk_debug("SMBUS Block complete\r\n"); -#else - print_debug("SMBUS Block complete\r\n"); -#endif - return 0; -}
Modified: trunk/coreboot-v2/src/southbridge/intel/i82801gx/i82801gx_usb.c =================================================================== --- trunk/coreboot-v2/src/southbridge/intel/i82801gx/i82801gx_usb.c 2009-03-11 14:48:20 UTC (rev 3990) +++ trunk/coreboot-v2/src/southbridge/intel/i82801gx/i82801gx_usb.c 2009-03-11 14:54:18 UTC (rev 3991) @@ -1,12 +1,12 @@ /* * This file is part of the coreboot project. * - * Copyright (C) 2008 coresystems GmbH + * Copyright (C) 2008-2009 coresystems GmbH * - * 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 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; version 2 of + * the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -42,6 +42,21 @@ printk_debug("done.\n"); }
+static void usb_set_subsystem(device_t dev, unsigned vendor, unsigned device) +{ + if (!vendor || !device) { + pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID, + pci_read_config32(dev, PCI_VENDOR_ID)); + } else { + pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID, + ((device & 0xffff) << 16) | (vendor & 0xffff)); + } +} + +static struct pci_operations usb_pci_ops = { + .set_subsystem = usb_set_subsystem, +}; + static struct device_operations usb_ops = { .read_resources = pci_dev_read_resources, .set_resources = pci_dev_set_resources, @@ -49,6 +64,7 @@ .init = usb_init, .scan_bus = 0, .enable = i82801gx_enable, + .ops_pci = &usb_pci_ops, };
/* 82801GB/GR/GDH/GBM/GHM/GU (ICH7/ICH7R/ICH7DH/ICH7-M/ICH7-M DH/ICH7-U) */
Added: trunk/coreboot-v2/src/southbridge/intel/i82801gx/i82801gx_usb_debug.c =================================================================== --- trunk/coreboot-v2/src/southbridge/intel/i82801gx/i82801gx_usb_debug.c (rev 0) +++ trunk/coreboot-v2/src/southbridge/intel/i82801gx/i82801gx_usb_debug.c 2009-03-11 14:54:18 UTC (rev 3991) @@ -0,0 +1,36 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2009 coresystems GmbH + * + * 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; version 2 of the License. + * + * 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 + */ + +// An arbitrary address for the BAR +#define EHCI_BAR 0xFEF00000 +// These could be read from DEBUG_BASE (0:1d.7 R 0x5A 16bit) +#define EHCI_BAR_INDEX 0x10 +#define EHCI_DEBUG_OFFSET 0xA0 + +static void set_debug_port(unsigned port) +{ + // Nothing for now? +} + +static void i82801gx_enable_usbdebug_direct(unsigned port) +{ + pci_write_config32(PCI_DEV(0, 0x1d, 7), EHCI_BAR_INDEX, EHCI_BAR); + pci_write_config8(PCI_DEV(0, 0x1d, 7), 0x04, 0x2); // Memory Space Enable +} +
Modified: trunk/coreboot-v2/src/southbridge/intel/i82801gx/i82801gx_usb_ehci.c =================================================================== --- trunk/coreboot-v2/src/southbridge/intel/i82801gx/i82801gx_usb_ehci.c 2009-03-11 14:48:20 UTC (rev 3990) +++ trunk/coreboot-v2/src/southbridge/intel/i82801gx/i82801gx_usb_ehci.c 2009-03-11 14:54:18 UTC (rev 3991) @@ -1,12 +1,12 @@ /* * This file is part of the coreboot project. * - * Copyright (C) 2008 coresystems GmbH + * Copyright (C) 2008-2009 coresystems GmbH * - * 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 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; version 2 of + * the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -23,14 +23,23 @@ #include <device/pci.h> #include <device/pci_ids.h> #include "i82801gx.h" +#if CONFIG_USBDEBUG_DIRECT +#include <usbdebug_direct.h> +#endif +#include <arch/io.h>
static void usb_ehci_init(struct device *dev) { + struct resource *res; + u8 *base; u32 reg32; + u8 reg8;
printk_debug("EHCI: Setting up controller.. "); reg32 = pci_read_config32(dev, PCI_COMMAND); - pci_write_config32(dev, PCI_COMMAND, reg32 | PCI_COMMAND_MASTER); + reg32 |= PCI_COMMAND_MASTER; + reg32 |= PCI_COMMAND_SERR; + pci_write_config32(dev, PCI_COMMAND, reg32);
reg32 = pci_read_config32(dev, 0xdc); reg32 |= (1 << 31) | (1 << 27); @@ -41,11 +50,21 @@ reg32 |= (2 << 2) | (1 << 29) | (1 << 17); pci_write_config32(dev, 0xfc, reg32);
+ /* Clear any pending port changes */ + res = find_resource(dev, 0x10); + base =(u8 *)res->base; + reg32 = readl(base + 0x24) | (1 << 2); + writel(base + 0x24, reg32); + + /* workaround */ + reg8 = pci_read_config8(dev, 0x84); + reg8 |= (1 << 4); + pci_write_config8(dev, 0x84, reg8); + printk_debug("done.\n"); }
-static void usb_ehci_set_subsystem(device_t dev, unsigned vendor, - unsigned device) +static void usb_ehci_set_subsystem(device_t dev, unsigned vendor, unsigned device) { u8 access_cntl;
@@ -54,14 +73,42 @@ /* 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)); + if (!vendor || !device) { + pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID, + pci_read_config32(dev, PCI_VENDOR_ID)); + } else { + pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID, + ((device & 0xffff) << 16) | (vendor & 0xffff)); + }
/* Restore protection. */ pci_write_config8(dev, 0x80, access_cntl); }
+static void usb_ehci_set_resources(struct device *dev) +{ +#if CONFIG_USBDEBUG_DIRECT + struct resource *res; + u32 base; + u32 usb_debug; + + usb_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(usb_debug); + if (!res) return; + base = res->base; + set_ehci_base(base); + report_resource_stored(dev, res, ""); +#endif +} + + + static struct pci_operations lops_pci = { .set_subsystem = &usb_ehci_set_subsystem, };
Modified: trunk/coreboot-v2/src/southbridge/intel/i82801gx/i82801gx_watchdog.c =================================================================== --- trunk/coreboot-v2/src/southbridge/intel/i82801gx/i82801gx_watchdog.c 2009-03-11 14:48:20 UTC (rev 3990) +++ trunk/coreboot-v2/src/southbridge/intel/i82801gx/i82801gx_watchdog.c 2009-03-11 14:54:18 UTC (rev 3991) @@ -1,12 +1,12 @@ /* * This file is part of the coreboot project. * - * Copyright (C) 2008 coresystems GmbH + * Copyright (C) 2008-2009 coresystems GmbH * - * 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 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; version 2 of + * the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of