1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <device/device.h>
4 #include <device/pci.h>
5 #include <device/pci_ops.h>
10 void i82801dx_enable(struct device
*dev
)
12 unsigned int index
= 0;
13 uint8_t bHasDisableBit
= 0;
14 uint16_t cur_disable_mask
, new_disable_mask
;
16 // all 82801dbm devices are in bus 0
17 unsigned int devfn
= PCI_DEVFN(0x1f, 0); // lpc
18 struct device
*lpc_dev
= pcidev_path_on_root(devfn
); // 0
22 // Calculate disable bit position for specified device:function
23 // NOTE: For ICH-4, only the following devices can be disabled:
24 // D31: F0, F1, F3, F5, F6,
25 // D29: F0, F1, F2, F7
27 if (PCI_SLOT(dev
->path
.pci
.devfn
) == 31) {
28 index
= PCI_FUNC(dev
->path
.pci
.devfn
);
44 index
= 14; // D31:F0 bit is an exception
46 } else if (PCI_SLOT(dev
->path
.pci
.devfn
) == 29) {
47 index
= 8 + PCI_FUNC(dev
->path
.pci
.devfn
);
49 if ((PCI_FUNC(dev
->path
.pci
.devfn
) < 3)
50 || (PCI_FUNC(dev
->path
.pci
.devfn
) == 7))
55 cur_disable_mask
= pci_read_config16(lpc_dev
, FUNC_DIS
);
56 new_disable_mask
= cur_disable_mask
& ~(1 << index
); // enable it
58 new_disable_mask
|= (1 << index
); // disable it
60 if (new_disable_mask
!= cur_disable_mask
) {
61 pci_write_config16(lpc_dev
, FUNC_DIS
, new_disable_mask
);
66 struct chip_operations southbridge_intel_i82801dx_ops
= {
67 CHIP_NAME("Intel ICH4/ICH4-M (82801Dx) Series Southbridge")
68 .enable_dev
= i82801dx_enable
,