summaryrefslogtreecommitdiff
path: root/src/southbridge/intel/i3100/i3100.c
diff options
context:
space:
mode:
authorEd Swierk <eswierk@arastra.com>2008-04-01 17:14:57 +0000
committerEd Swierk <eswierk@arastra.com>2008-04-01 17:14:57 +0000
commit2b85b6311f1b7497da3484dc9369e80c9140ae5c (patch)
tree16fe3ff636026bf86c40c4ba32a85fc9a579398f /src/southbridge/intel/i3100/i3100.c
parent23cd49ab807d7d3ce496740000ad588eb5a0a16a (diff)
Setting an integrated southbridge device (like SATA or USB2.0) to
"off" in Config.lb should cause the PCI device not to respond to configuration requests. Replace the existing code that I naively copied from esb6300 with something that actually works on the 3100. Signed-off-by: Ed Swierk <eswierk@arastra.com> Acked-by: Uwe Hermann <uwe@hermann-uwe.de> git-svn-id: svn://svn.coreboot.org/coreboot/trunk@3209 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
Diffstat (limited to 'src/southbridge/intel/i3100/i3100.c')
-rw-r--r--src/southbridge/intel/i3100/i3100.c57
1 files changed, 25 insertions, 32 deletions
diff --git a/src/southbridge/intel/i3100/i3100.c b/src/southbridge/intel/i3100/i3100.c
index 046bcaeb08..2d08b42d0d 100644
--- a/src/southbridge/intel/i3100/i3100.c
+++ b/src/southbridge/intel/i3100/i3100.c
@@ -18,52 +18,45 @@
*
*/
-/* This code is based on src/southbridge/intel/esb6300/esb6300.c */
-
#include <console/console.h>
#include <device/device.h>
#include <device/pci.h>
-#include <device/pci_ids.h>
#include "i3100.h"
void i3100_enable(device_t dev)
{
device_t lpc_dev;
- u32 index = 0;
- u16 reg_old, reg;
+ u8 func;
+ volatile u32 *disable;
- /* See if we are behind the i3100 PCI bridge */
- lpc_dev = dev_find_slot(dev->bus->secondary, PCI_DEVFN(0x1f, 0));
- 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;
- }
- if ((!lpc_dev) || (index >= 16) || ((1 << index) & 0x3091)) {
+ if (dev->enabled)
return;
- }
- if ((lpc_dev->vendor != PCI_VENDOR_ID_INTEL) ||
- (lpc_dev->device != PCI_DEVICE_ID_INTEL_3100_LPC)) {
- u32 id;
- id = pci_read_config32(lpc_dev, PCI_VENDOR_ID);
- if (id != (PCI_VENDOR_ID_INTEL |
- (PCI_DEVICE_ID_INTEL_3100_LPC << 16))) {
- return;
- }
- }
- reg = reg_old = pci_read_config16(lpc_dev, 0xf2);
- reg &= ~(1 << index);
- if (!dev->enabled) {
- reg |= (1 << index);
- }
- if (reg != reg_old) {
- pci_write_config16(lpc_dev, 0xf2, reg);
+ /*
+ * To disable an integrated southbridge device, set the corresponding
+ * flag in the Function Disable register.
+ */
+
+ /* Temporarily enable the root complex register block at 0xa0000000. */
+ lpc_dev = dev_find_slot(0x0, PCI_DEVFN(0x1f, 0x0));
+ pci_write_config32(lpc_dev, 0xf0, 0xa0000000 | (1 << 0));
+ disable = (volatile u32 *) 0xa0003418;
+ func = PCI_FUNC(dev->path.u.pci.devfn);
+ switch (PCI_SLOT(dev->path.u.pci.devfn)) {
+ case 0x1f: /* LPC (fn0), SATA (fn2), SMBus (fn3) */
+ *disable |= (1 << (func == 0x0 ? 14 : func));
+ break;
+ case 0x1d: /* UHCI (fn0, fn1), EHCI (fn7) */
+ *disable |= (1 << (func + 8));
+ break;
+ case 0x1c: /* PCIe ports B0-B3 (fn0-fn3) */
+ *disable |= (1 << (func + 16));
+ break;
}
+ /* Disable the root complex register block. */
+ pci_write_config32(lpc_dev, 0xf0, 0);
}
struct chip_operations southbridge_intel_i3100_ops = {
CHIP_NAME("Intel 3100 Southbridge")
- .enable_dev = i3100_enable,
};