2 * This file is part of the coreboot project.
4 * Copyright (C) 2008-2009 coresystems GmbH
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; version 2 of
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 #include <console/console.h>
23 #include <device/device.h>
24 #include <device/pci.h>
27 static int pch_revision_id = -1;
29 int pch_silicon_revision(void)
31 if (pch_revision_id < 0)
32 pch_revision_id = pci_read_config8(
33 dev_find_slot(0, PCI_DEVFN(0x1f, 0)),
35 return pch_revision_id;
38 /* Set bit in Function Disble register to hide this device */
39 static void pch_hide_devfn(unsigned devfn)
42 case PCI_DEVFN(22, 0): /* MEI #1 */
43 RCBA32_OR(FD2, PCH_DISABLE_MEI1);
45 case PCI_DEVFN(22, 1): /* MEI #2 */
46 RCBA32_OR(FD2, PCH_DISABLE_MEI2);
48 case PCI_DEVFN(22, 2): /* IDE-R */
49 RCBA32_OR(FD2, PCH_DISABLE_IDER);
51 case PCI_DEVFN(22, 3): /* KT */
52 RCBA32_OR(FD2, PCH_DISABLE_KT);
54 case PCI_DEVFN(25, 0): /* Gigabit Ethernet */
55 RCBA32_OR(BUC, PCH_DISABLE_GBE);
57 case PCI_DEVFN(26, 0): /* EHCI #2 */
58 RCBA32_OR(FD, PCH_DISABLE_EHCI2);
60 case PCI_DEVFN(27, 0): /* HD Audio Controller */
61 RCBA32_OR(FD, PCH_DISABLE_HD_AUDIO);
63 case PCI_DEVFN(28, 0): /* PCI Express Root Port 1 */
64 case PCI_DEVFN(28, 1): /* PCI Express Root Port 2 */
65 case PCI_DEVFN(28, 2): /* PCI Express Root Port 3 */
66 case PCI_DEVFN(28, 3): /* PCI Express Root Port 4 */
67 case PCI_DEVFN(28, 4): /* PCI Express Root Port 5 */
68 case PCI_DEVFN(28, 5): /* PCI Express Root Port 6 */
69 case PCI_DEVFN(28, 6): /* PCI Express Root Port 7 */
70 case PCI_DEVFN(28, 7): /* PCI Express Root Port 8 */
71 RCBA32_OR(FD, PCH_DISABLE_PCIE(PCI_FUNC(devfn)));
73 case PCI_DEVFN(29, 0): /* EHCI #1 */
74 RCBA32_OR(FD, PCH_DISABLE_EHCI1);
76 case PCI_DEVFN(30, 0): /* PCI-to-PCI Bridge */
77 RCBA32_OR(FD, PCH_DISABLE_P2P);
79 case PCI_DEVFN(31, 0): /* LPC */
80 RCBA32_OR(FD, PCH_DISABLE_LPC);
82 case PCI_DEVFN(31, 2): /* SATA #1 */
83 RCBA32_OR(FD, PCH_DISABLE_SATA1);
85 case PCI_DEVFN(31, 3): /* SMBUS */
86 RCBA32_OR(FD, PCH_DISABLE_SMBUS);
88 case PCI_DEVFN(31, 5): /* SATA #22 */
89 RCBA32_OR(FD, PCH_DISABLE_SATA2);
91 case PCI_DEVFN(31, 6): /* Thermal Subsystem */
92 RCBA32_OR(FD, PCH_DISABLE_THERMAL);
97 #define IOBP_RETRY 1000
98 static inline int iobp_poll(void)
100 unsigned try = IOBP_RETRY;
104 data = RCBA32(IOBPS);
110 printk(BIOS_ERR, "IOBP timeout\n");
114 void pch_iobp_update(u32 address, u32 andvalue, u32 orvalue)
118 /* Set the address */
119 RCBA32(IOBPIRI) = address;
122 if (pch_silicon_revision() >= PCH_STEP_B0)
123 RCBA32(IOBPS) = IOBPS_RW_BX;
125 RCBA32(IOBPS) = IOBPS_READ_AX;
130 data = RCBA32(IOBPD);
134 /* Check for successful transaction */
135 if ((RCBA32(IOBPS) & 0x6) != 0) {
136 printk(BIOS_ERR, "IOBP read 0x%08x failed\n", address);
140 /* Update the data */
145 if (pch_silicon_revision() >= PCH_STEP_B0)
146 RCBA32(IOBPS) = IOBPS_RW_BX;
148 RCBA32(IOBPS) = IOBPS_WRITE_AX;
152 /* Write IOBP data */
153 RCBA32(IOBPD) = data;
158 /* Check if any port in set X to X+3 is enabled */
159 static int pch_pcie_check_set_enabled(device_t dev)
163 int dev_func = PCI_FUNC(dev->path.pci.devfn);
165 printk(BIOS_DEBUG, "%s: check set enabled\n", dev_path(dev));
167 /* Go through static device tree list of devices
168 * because enumeration is still in progress */
169 for (port = all_devices; port; port = port->next) {
170 /* Only care about PCIe root ports */
171 if (PCI_SLOT(port->path.pci.devfn) !=
172 PCI_SLOT(dev->path.pci.devfn))
175 /* Check if port is in range and enabled */
176 port_func = PCI_FUNC(port->path.pci.devfn);
177 if (port_func >= dev_func &&
178 port_func < (dev_func + 4) &&
183 /* None of the ports in this set are enabled */
187 void pch_enable(device_t dev)
192 printk(BIOS_DEBUG, "%s: Disabling device\n", dev_path(dev));
195 * PCIE Power Savings for stepping B1+:
197 * If PCIe 0-3 disabled set Function 0 0xE2[0] = 1
198 * If PCIe 4-7 disabled set Function 4 0xE2[0] = 1
200 * This check is done here instead of pcie driver
201 * because the pcie driver enable() handler is not
202 * called unless the device is enabled.
204 if (pch_silicon_revision() >= PCH_STEP_B1 &&
205 PCI_SLOT(dev->path.pci.devfn) == PCH_PCIE_DEV_SLOT &&
206 (PCI_FUNC(dev->path.pci.devfn) == 0 ||
207 PCI_FUNC(dev->path.pci.devfn) == 4)) {
208 if (!pch_pcie_check_set_enabled(dev)) {
209 u8 reg8 = pci_read_config8(dev, 0xe2);
211 pci_write_config8(dev, 0xe2, reg8);
215 /* Ensure memory, io, and bus master are all disabled */
216 reg32 = pci_read_config32(dev, PCI_COMMAND);
217 reg32 &= ~(PCI_COMMAND_MASTER |
218 PCI_COMMAND_MEMORY | PCI_COMMAND_IO );
219 pci_write_config32(dev, PCI_COMMAND, reg32);
221 /* Hide this device if possible */
222 pch_hide_devfn(dev->path.pci.devfn);
225 reg32 = pci_read_config32(dev, PCI_COMMAND);
226 reg32 |= PCI_COMMAND_SERR;
227 pci_write_config32(dev, PCI_COMMAND, reg32);
231 struct chip_operations southbridge_intel_bd82x6x_ops = {
232 CHIP_NAME("Intel Series 6 (" CONFIG_PCH_CHIP_NAME ") Southbridge")
233 .enable_dev = pch_enable,