1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <console/console.h>
4 #include <device/device.h>
5 #include <device/pci.h>
6 #include <device/pci_ops.h>
7 #include <device/pci_ids.h>
11 /* Low Power variant has 6 root ports. */
12 #define NUM_ROOT_PORTS 6
14 struct root_port_config
{
15 /* RPFN is a write-once register so keep a copy until it is written */
19 struct device
*ports
[NUM_ROOT_PORTS
];
22 static struct root_port_config rpc
;
24 static inline int root_port_is_first(struct device
*dev
)
26 return PCI_FUNC(dev
->path
.pci
.devfn
) == 0;
29 static inline int root_port_is_last(struct device
*dev
)
31 return PCI_FUNC(dev
->path
.pci
.devfn
) == (rpc
.num_ports
- 1);
34 /* Root ports are numbered 1..N in the documentation. */
35 static inline int root_port_number(struct device
*dev
)
37 return PCI_FUNC(dev
->path
.pci
.devfn
) + 1;
40 static void pci_init(struct device
*dev
)
44 printk(BIOS_DEBUG
, "Initializing ICH7 PCIe bridge.\n");
46 /* Enable Bus Master */
47 pci_or_config16(dev
, PCI_COMMAND
, PCI_COMMAND_MASTER
);
49 /* Set Cache Line Size to 0x10 */
50 // This has no effect but the OS might expect it
51 pci_write_config8(dev
, PCI_CACHE_LINE_SIZE
, 0x10);
53 pci_and_config16(dev
, PCI_BRIDGE_CONTROL
, ~PCI_BRIDGE_CTL_PARITY
);
55 /* Enable IO xAPIC on this PCIe port */
56 pci_or_config32(dev
, 0xd8, 1 << 7);
58 /* Enable Backbone Clock Gating */
59 pci_or_config32(dev
, 0xe1, (1 << 3) | (1 << 2) | (1 << 1) | (1 << 0));
61 /* Set VC0 transaction class */
62 pci_update_config32(dev
, 0x114, ~0x000000ff, 1);
64 /* Mask completion timeouts */
65 pci_or_config32(dev
, 0x148, 1 << 14);
67 /* Enable common clock configuration */
68 // Are there cases when we don't want that?
69 pci_or_config16(dev
, 0x50, 1 << 6);
71 /* Clear errors in status registers. FIXME: Do something? */
72 reg16
= pci_read_config16(dev
, 0x06);
74 pci_write_config16(dev
, 0x06, reg16
);
76 reg16
= pci_read_config16(dev
, 0x1e);
78 pci_write_config16(dev
, 0x1e, reg16
);
81 static int get_num_ports(void)
83 struct device
*dev
= pcidev_on_root(31, 0);
84 if (pci_read_config32(dev
, FDVCT
) & PCIE_4_PORTS_MAX
)
90 static void root_port_init_config(struct device
*dev
)
94 if (root_port_is_first(dev
)) {
95 rpc
.orig_rpfn
= RCBA32(RPFN
);
96 rpc
.new_rpfn
= rpc
.orig_rpfn
;
97 rpc
.num_ports
= get_num_ports();
100 rp
= root_port_number(dev
);
101 if (rp
> rpc
.num_ports
) {
102 printk(BIOS_ERR
, "Found Root Port %d, expecting %d\n", rp
, rpc
.num_ports
);
106 /* Cache pci device. */
107 rpc
.ports
[rp
- 1] = dev
;
110 /* Update devicetree with new Root Port function number assignment */
111 static void ich_pcie_device_set_func(int index
, int pci_func
)
114 unsigned int new_devfn
;
116 dev
= rpc
.ports
[index
];
118 /* Set the new PCI function field for this Root Port. */
119 rpc
.new_rpfn
&= ~RPFN_FNMASK(index
);
120 rpc
.new_rpfn
|= RPFN_FNSET(index
, pci_func
);
122 /* Determine the new devfn for this port */
123 new_devfn
= PCI_DEVFN(ICH_PCIE_DEV_SLOT
, pci_func
);
125 if (dev
->path
.pci
.devfn
!= new_devfn
) {
127 "ICH: PCIe map %02x.%1x -> %02x.%1x\n",
128 PCI_SLOT(dev
->path
.pci
.devfn
),
129 PCI_FUNC(dev
->path
.pci
.devfn
),
130 PCI_SLOT(new_devfn
), PCI_FUNC(new_devfn
));
132 dev
->path
.pci
.devfn
= new_devfn
;
136 static void root_port_commit_config(struct device
*dev
)
139 bool coalesce
= false;
141 if (dev
->chip_info
!= nullptr) {
142 const struct southbridge_intel_i82801gx_config
*config
= dev
->chip_info
;
143 coalesce
= config
->pcie_port_coalesce
;
146 if (!rpc
.ports
[0]->enabled
)
149 for (i
= 0; i
< rpc
.num_ports
; i
++) {
150 struct device
*pcie_dev
;
152 pcie_dev
= rpc
.ports
[i
];
154 if (pcie_dev
== nullptr) {
155 printk(BIOS_ERR
, "Root Port %d device is nullptr?\n", i
+ 1);
159 if (pcie_dev
->enabled
)
162 printk(BIOS_DEBUG
, "%s: Disabling device\n", dev_path(pcie_dev
));
164 /* Disable this device if possible */
165 i82801gx_enable(pcie_dev
);
171 /* For all Root Ports N enabled ports get assigned the lower
172 * PCI function number. The disabled ones get upper PCI
173 * function numbers. */
175 for (i
= 0; i
< rpc
.num_ports
; i
++) {
176 if (!rpc
.ports
[i
]->enabled
)
178 ich_pcie_device_set_func(i
, current_func
);
182 /* Allocate the disabled devices' PCI function number. */
183 for (i
= 0; i
< rpc
.num_ports
; i
++) {
184 if (rpc
.ports
[i
]->enabled
)
186 ich_pcie_device_set_func(i
, current_func
);
191 printk(BIOS_SPEW
, "ICH: RPFN 0x%08x -> 0x%08x\n", rpc
.orig_rpfn
, rpc
.new_rpfn
);
192 RCBA32(RPFN
) = rpc
.new_rpfn
;
195 static void ich_pcie_enable(struct device
*dev
)
197 /* Add this device to the root port config structure. */
198 root_port_init_config(dev
);
201 * When processing the last PCIe root port we can now
202 * update the Root Port Function Number and Hide register.
204 if (root_port_is_last(dev
))
205 root_port_commit_config(dev
);
208 static struct device_operations device_ops
= {
209 .read_resources
= pci_bus_read_resources
,
210 .set_resources
= pci_dev_set_resources
,
211 .enable_resources
= pci_bus_enable_resources
,
213 .enable
= ich_pcie_enable
,
214 .scan_bus
= pci_scan_bridge
,
215 .ops_pci
= &pci_dev_ops_pci
,
218 static const unsigned short i82801gx_pcie_ids
[] = {
219 0x27d0, /* 82801GB/GR/GDH/GBM/GHM (ICH7/ICH7R/ICH7DH/ICH7-M/ICH7-M DH) */
220 0x27d2, /* 82801GB/GR/GDH/GBM/GHM (ICH7/ICH7R/ICH7DH/ICH7-M/ICH7-M DH) */
221 0x27d4, /* 82801GB/GR/GDH/GBM/GHM (ICH7/ICH7R/ICH7DH/ICH7-M/ICH7-M DH) */
222 0x27d6, /* 82801GB/GR/GDH/GBM/GHM (ICH7/ICH7R/ICH7DH/ICH7-M/ICH7-M DH) */
223 0x27e0, /* 82801GR/GDH/GHM (ICH7R/ICH7DH/ICH7-M DH) */
224 0x27e2, /* 82801GR/GDH/GHM (ICH7R/ICH7DH/ICH7-M DH) */
228 static const struct pci_driver i82801gx_pcie __pci_driver
= {
230 .vendor
= PCI_VID_INTEL
,
231 .devices
= i82801gx_pcie_ids
,